Java中的多线程AES加密

问题描述

正如标题所说,我正在尝试使用2个线程加密文件并使用1个线程解密。 由于加密不是线程安全的,因此我使用FileChannel指定在第二个线程中读取的位置。 我使用的是512字节缓冲区,因此我将文件大小除以1024,从而获得在while中进行的迭代,以到达文件前半部分的末尾。 第二个线程在第一个线程结束后立即开始,并迭代直到文件结束。 解密功能一次只能读取一个文件,然后在第二个文件的末尾附加第二个文件。

我已经对图像进行了测试,但是不幸的是,解密后只能看到图像的前半部分,其余部分是白色的。 解密结束时,我得到Error while decrypting: java.io.IOException: javax.crypto.BadPaddingException

EDIT1:我想我已经迈出了一步,现在我可以通过在2个不同的地方读取文件来实现多线程加密,但是解密后我仍然得到Error while decrypting: java.io.IOException: javax.crypto.BadPaddingException

    public void encrypt(File inputFile,File outputFile,String secret,int threadNum,long iteration) 
    {       
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE,secretKey);
            
            FileInputStream fis = new FileInputStream(inputFile);
            FileOutputStream fos = new FileOutputStream(outputFile);
            
            byte[] buffer = new byte[512];
            long val = inputFile.length()/100,numIteration = 0;
            int count;
            if(threadNum == 1)
            {
                while(true)
                {
                    if(numIteration == iteration)
                    {
                        fis.read(buffer);
                        fos.write(cipher.doFinal(buffer));
                        System.out.println("Dofinal 1°");
                        break;
                    }
                    else {
                        fis.read(buffer);
                        fos.write(cipher.update(buffer));
                    }
                    System.out.println("Num iteration: "+numIteration);
                    numIteration++;
                }
            }
            else if(threadNum == 2)
            {
                while(numIteration <= iteration)
                {
                    if(numIteration <= iteration/2)
                    {
                        fis.skip(512);
                    }
                    else if(numIteration >= iteration/2) {
                        fis.read(buffer);
                        fos.write(cipher.update(buffer));
                        System.out.println("Iteration"+numIteration);
                    }
                    else if(numIteration == iteration)
                    {
                        fis.read(buffer);
                        fos.write(cipher.doFinal(new byte[(int) inputFile.length()%512]));
                        break;
                    }
                    System.out.println("NumIteration: "+numIteration);
                    numIteration++;
                }
            }
        }
        catch (Exception e) 
        {
            System.out.println("Error while encrypting: " + e.toString());
        }
    }

    public void decrypt(File inputFile[],String secret) 
    {
        System.out.println("Decryption");
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE,secretKey);
            
            for(int i = 0; i < 2; i++)
            {
                CipherInputStream in = new CipherInputStream(new FileInputStream(inputFile[i]),cipher);
                CountingInputStream cis = new CountingInputStream(in);
                
                FileOutputStream out;
                
                if(i == 0)
                    out = new FileOutputStream(outputFile);
                else 
                    out = new FileOutputStream(outputFile,true);

                CountingOutputStream cos = new CountingOutputStream(out);

                int count;
                double val = (inputFile[i].length()/100);
                byte[] buffer = new byte[512];
                while((count = cis.read(buffer)) != -1)
                {
                    cos.write(buffer,count);
                    cos.flush();
                }
                cis.close();
                cos.close();
            }
        } 
        catch (Exception e) 
        {
            System.out.println("Error while decrypting: " + e.toString());
        }
    }

解决方法

我设法实现了双线程加密,使用i5 10210u 4c 8t对48,5 mb文件(从0.57到0.41 s)的性能提高了约28%。 通过根据CPU内核数增加线程数来实现更高的性能

代码如下:

    public void encrypt(File inputFile,File outputFile,String secret,int threadNum,long iteration) 
    {       
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE,secretKey);
            
            FileInputStream fis = new FileInputStream(inputFile);
            FileOutputStream fos = new FileOutputStream(outputFile);
            
            byte[] buffer = new byte[512];
            long numIteration = 1;
            
            if(threadNum == 1)
            {
                while(true)
                {
                    if(numIteration == iteration)
                    {
                        fis.read(buffer);
                        fos.write(cipher.doFinal(buffer));
                        break;
                    }
                    else 
                    {
                        fis.read(buffer);
                        fos.write(cipher.update(buffer));
                    }
                    numIteration++;
                }
            }
            else if(threadNum == 2)
            {
                while(numIteration <= iteration)
                {
                    if(numIteration == iteration)
                    {
                        byte[] f = new byte[(int) inputFile.length()%512];
                        fis.read(f);
                        fos.write(cipher.doFinal(f));
                        break;
                    }
                    else if(numIteration < iteration/2)
                    {
                        fis.skip(512);
                    }
                    else if(numIteration >= iteration/2 && numIteration < iteration) 
                    {
                        fis.read(buffer);
                        fos.write(cipher.update(buffer));
                    }
                    numIteration++;
                }
            }
            fis.close();
            fos.close();
        }
        catch (Exception e) 
        {
            System.out.println("Error while encrypting: " + e.toString());
        }
    }

    public void decrypt(File inputFile[],String secret) 
    {
        try
        {
            setKey(secret);
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE,secretKey);
            
            for(int i = 0; i < 2; i++)
            {               
                CipherInputStream in = new CipherInputStream(new FileInputStream(inputFile[i]),cipher);
                CountingInputStream cis = new CountingInputStream(in);
                
                FileOutputStream out;
                
                if(i == 0)
                    out = new FileOutputStream(outputFile);
                else 
                    out = new FileOutputStream(outputFile,true);

                CountingOutputStream cos = new CountingOutputStream(out);

                int count;
                double val = (inputFile[i].length()/100);
                byte[] buffer = new byte[512];
                
                while((count = cis.read(buffer)) != -1)
                {
                    cos.write(buffer,count);
                    cos.flush();
                    System.out.println("Percentuale: "+cos.getCount()/val+"%");
                }
                cis.close();
                cos.close();
            }
        } 
        catch (Exception e) 
        {
            System.out.println("Error while decrypting: " + e.toString());
        }
    }

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...