我得到鑑於最終塊未正確填充錯誤,同時解密大型加密文件上的AES/CBC/PKCS5Padding密碼。解密AES/CBC/PKCS5Padding錯誤:鑑於最終塊未正確填充
我覺得這個問題是由於在cipher.init()方法中加入了錯誤的初始化向量造成的。
我無法在運行時讀取整個文件,所以我需要加密固定大小的塊。在這一點上,我正在創建IV並將其存儲到.txt文件。但在解密方法中,我在每個解密週期使用相同的IV。我應該如何改變這一點?
加密:
void encrypt() throws Exception{
char[] password = passwordText.getText().toCharArray();
byte[] salt = new byte[8];
/* Creating and saving salt */
salt = saveSalt(salt);
/* Securing password */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 128);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
if (choosedFile != null) {
/* Choosing algorithm for decryption */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
/* Getting plain file */
CipherInputStream fis = new CipherInputStream(new FileInputStream(choosedFile), cipher);
CipherOutputStream fos = new CipherOutputStream(new FileOutputStream(choosedFile+".encrypted"), cipher);
/* Encrypting and Measuring */
long startTime = System.currentTimeMillis();
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] rawText = new byte[128];
int count;
while((count = fis.read(rawText)) > 0) {
System.out.println(count);
byte[] encryptedText = cipher.doFinal(rawText);
fos.write(encryptedText, 0, count);
}
long stopTime = System.currentTimeMillis();
fis.close();
fos.close();
/* Creating initialization vector and storing*/
byte[] iVector = cipher.getIV();
saveIVector(iVector);
text.setText(text.getText() + "File was encrypted in " + (stopTime - startTime) + "ms.\n");
}
}
解密:
void decrypt() throws Exception {
/* Getting salt */
byte[] salt = getSalt();
/* Getting initialization vector */
byte[] iVector = getIVector();
/* Getting user password */
char[] password = passwordText.getText().toCharArray();
/* Securing password */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 128);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
if (choosedFile != null) {
/* Choosing algorithm for decryption */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
/* Getting ciphered file */
CipherInputStream fis = new CipherInputStream(new FileInputStream(choosedFile), cipher);
CipherOutputStream fos = new CipherOutputStream(new FileOutputStream(choosedFile+".decrypted"), cipher);
/* Decrypting and Measuring */
long startTime = System.currentTimeMillis();
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iVector));
byte[] rawText = new byte[128];
int count;
while((count = fis.read(rawText)) > 0) {
byte[] encryptedText = cipher.doFinal(rawText);
fos.write(encryptedText, 0, count);
}
long stopTime = System.currentTimeMillis();
fis.close();
fos.close();
既然你指定PKCS#5加密和解密將錯誤確實是在一個錯誤由於參數不正確而導致解密(密鑰,iv,加密數據)。解密失敗,所以填充也是垃圾。重新處理問題只包括加密並以十六進制提供加密數據。使用小輸入使其變得簡單。提供[mcve]。由於該錯誤與加密相關,因此將所有其他代碼刪除。 – zaph
@ zaph對不起,我忘了提及加密和解密算法都工作得很好,直到我不得不將大文件剪切成固定大小的塊。Ergo,我不認爲需要加密數據的例子。但是我試圖加密和解密小文件。它以相同的結果結束。儘管如此,你是對的。加密不是應該的,但我不知道爲什麼。 – Amphoru