问题描述
正如标题所说,我正在尝试使用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());
}
}