Java JCA - 输入长度必须是填充解密器的 8 的倍数
Java JCA - Input length must be multiple of 8 for padded decypher
我目前正在使用 Java 的 JCA 完成大学课程的作业。
应用程序接收文件并使用 DES-ECB 对其进行加密(或解密)。 我完全知道这不是一种安全的加密算法。
我相信它加密得很好,但是在解密时它会爆炸并显示“输入长度必须是 8 的倍数”,即使原始消息是用 PKCS5 填充的。
我已经在 Whosebug 上阅读了所有关于这个问题的文献和问题,但是 none 的答案似乎解决了这个问题,这让我相信我在某种程度上破坏了 message/file。 ..
对于加密:
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, symmetricKey);
File file = new File(filePath);
FileOutputStream outputStream = new FileOutputStream("encrypted_"+file.getName());
CipherInputStream cipherStream = new CipherInputStream( new FileInputStream(file), cipher);
byte[] buffer = new byte[MAX_BUFFER]; //buffer para leitura
int bytes; //bytes a ler
//Encoder base64 - Apache Commons Codec
Base64 encoder = new Base64();
while ( (bytes = cipherStream.read(buffer)) != -1 ) {
byte[] encodedBuffer = encoder.encode(buffer);
outputStream.write(encodedBuffer, 0, bytes);
}
cipherStream.close();
outputStream.flush();
return outputStream;
解密用:
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, symmetricKey);
File file = new File(filePath);
FileInputStream cipheredStream = new FileInputStream(file);
FileOutputStream outputStream = new FileOutputStream("decrypted_"+file.getName());
CipherOutputStream cipherOutStream = new CipherOutputStream(outputStream, cipher);
byte[] buffer = new byte[MAX_BUFFER];
int bytes;
//Decoder base 64 - Apache Commons Codec
Base64 decoder = new Base64();
cipheredStream.read(buffer);
byte[] decodedBuffer = decoder.decode(buffer);
byte[] output = cipher.doFinal(decodedBuffer);
cipherOutStream.write(output);
//TODO bug here -> use this for big files
/*while ( (bytes = cipheredStream.read(buffer)) != -1 ) {
byte[] decodedBuffer = decoder.decode(buffer);
cipherOutStream.write(decodedBuffer, 0, bytes);
}*/
cipherOutStream.close();
cipheredStream.close();
return outputStream;
我试过使用 AES 无济于事;我试过不用padding,显然不行。
我只是迷路了,很高兴知道我做错了什么。
感谢@Topaco,使用 Base64InputStream 找到了解决方案。
因为解密是在解码之前完成的,所以它产生了那个错误。它通过执行此加密方面得到修复:
Base64OutputStream encoder = new Base64OutputStream(outputStream);
while ( (nBytes = cipherStream.read(buffer, 0, MAX_BUFFER)) != -1 )
encoder.write(buffer, 0, nBytes);
与解密方完全相反:
Base64InputStream decoder = new Base64InputStream(fileInputStream);
while ( (nBytes = decoder.read(buffer, 0, MAX_BUFFER)) != -1 )
cipherOutStream.write(buffer, 0, nBytes);
我目前正在使用 Java 的 JCA 完成大学课程的作业。 应用程序接收文件并使用 DES-ECB 对其进行加密(或解密)。 我完全知道这不是一种安全的加密算法。
我相信它加密得很好,但是在解密时它会爆炸并显示“输入长度必须是 8 的倍数”,即使原始消息是用 PKCS5 填充的。
我已经在 Whosebug 上阅读了所有关于这个问题的文献和问题,但是 none 的答案似乎解决了这个问题,这让我相信我在某种程度上破坏了 message/file。 ..
对于加密:
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, symmetricKey);
File file = new File(filePath);
FileOutputStream outputStream = new FileOutputStream("encrypted_"+file.getName());
CipherInputStream cipherStream = new CipherInputStream( new FileInputStream(file), cipher);
byte[] buffer = new byte[MAX_BUFFER]; //buffer para leitura
int bytes; //bytes a ler
//Encoder base64 - Apache Commons Codec
Base64 encoder = new Base64();
while ( (bytes = cipherStream.read(buffer)) != -1 ) {
byte[] encodedBuffer = encoder.encode(buffer);
outputStream.write(encodedBuffer, 0, bytes);
}
cipherStream.close();
outputStream.flush();
return outputStream;
解密用:
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, symmetricKey);
File file = new File(filePath);
FileInputStream cipheredStream = new FileInputStream(file);
FileOutputStream outputStream = new FileOutputStream("decrypted_"+file.getName());
CipherOutputStream cipherOutStream = new CipherOutputStream(outputStream, cipher);
byte[] buffer = new byte[MAX_BUFFER];
int bytes;
//Decoder base 64 - Apache Commons Codec
Base64 decoder = new Base64();
cipheredStream.read(buffer);
byte[] decodedBuffer = decoder.decode(buffer);
byte[] output = cipher.doFinal(decodedBuffer);
cipherOutStream.write(output);
//TODO bug here -> use this for big files
/*while ( (bytes = cipheredStream.read(buffer)) != -1 ) {
byte[] decodedBuffer = decoder.decode(buffer);
cipherOutStream.write(decodedBuffer, 0, bytes);
}*/
cipherOutStream.close();
cipheredStream.close();
return outputStream;
我试过使用 AES 无济于事;我试过不用padding,显然不行。
我只是迷路了,很高兴知道我做错了什么。
感谢@Topaco,使用 Base64InputStream 找到了解决方案。
因为解密是在解码之前完成的,所以它产生了那个错误。它通过执行此加密方面得到修复:
Base64OutputStream encoder = new Base64OutputStream(outputStream);
while ( (nBytes = cipherStream.read(buffer, 0, MAX_BUFFER)) != -1 )
encoder.write(buffer, 0, nBytes);
与解密方完全相反:
Base64InputStream decoder = new Base64InputStream(fileInputStream);
while ( (nBytes = decoder.read(buffer, 0, MAX_BUFFER)) != -1 )
cipherOutStream.write(buffer, 0, nBytes);