[英]Double encryption / decryption fails but single does not - AES 256 bit
因此,這種特殊情況非常普遍,但是我的問題與通常提出的問題略有不同。
我已經定義了AES解密和加密功能,如下所示:
public static byte[] encrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes)
throws java.io.UnsupportedEncodingException,
NoSuchAlgorithmException,
NoSuchPaddingException,
InvalidKeyException,
InvalidAlgorithmParameterException,
IllegalBlockSizeException,
BadPaddingException {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
Cipher cipher;
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
return cipher.doFinal(textBytes);
}
public static byte[] decrypt(byte[] ivBytes, byte[] keyBytes, byte[] textBytes)
throws java.io.UnsupportedEncodingException,
NoSuchAlgorithmException,
NoSuchPaddingException,
InvalidKeyException,
InvalidAlgorithmParameterException,
IllegalBlockSizeException,
BadPaddingException {
AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
SecretKeySpec newKey = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
return cipher.doFinal(textBytes);
}
現在,如果我像這樣執行一次解密:
System.out.println(Arrays.toString(
AES256Cipher.decrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(aKeys[a]),
AES256Cipher.encrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(aKeys[a]),
AES256Cipher.encrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(bKeys[b]), HexBytePlainWriter.hexStringToByteArray(zkeys[a^b]))
)
)));
字節數組輸出就可以了。 而如果我執行雙重加密/解密:
System.out.println("dec: " + HexBytePlainWriter.ByteToHexString(
AES256Cipher.decrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(aKeys[a]),
AES256Cipher.decrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(bKeys[b]),
AES256Cipher.encrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(aKeys[a]),
AES256Cipher.encrypt(ivBytes, HexBytePlainWriter.hexStringToByteArray(bKeys[b]), HexBytePlainWriter.hexStringToByteArray(zkeys[a^b]))
)
))));
我得到了著名的javax.crypto.BadPaddingException: Given final block not properly padded
Exception。 請注意, a
和b
只是整數(假設它們都為0)。 當前,IVBytes只是一個大小為16的空字節數組,用new byte[16]
。 aKeys
和bKeys
都是帶有AES加密(隨機)字符串(長度為32個字節)的String數組。
這些是我使用的輔助函數(將byte []轉換為十六進制字符串,反之亦然):
public static String ByteToHexString (byte[] data) {
StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfbyte = (b >>> 4) & 0x0F;
int two_halfs = 0;
do {
buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
halfbyte = b & 0x0F;
} while (two_halfs++ < 1);
}
return buf.toString();
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
我懷疑第一次解密的輸出會使密文格式錯誤,以至於外部會引發異常。 我檢查了大小,外部部分輸出了32個字節,因此應該可以。 這不符合PKC5Padding嗎?
任何幫助深表感謝。
看來我的最小示例是錯誤的:我首先使用鍵B而不是A。但是Jon Skeet確實給了我一個主意。 如果我有什么新東西,我會編輯。
這個想法是正確的。 我正在遍歷一個亂碼的真值表(對於那些感興趣的人,請查看Wikipedia文章 )並檢查所有可能的密文(CT)。 問題是,如果您選擇了不正確的CT並對其進行了雙重解密,則它將拋出異常,因為第一次解密會返回垃圾。 只需檢查表中的鍵即可解決此問題。
您使用錯誤的密鑰進行解密。 您正在使用密鑰B加密,然后使用密鑰A加密結果。然后嘗試使用密鑰B解密該結果,並使用密鑰A解密最終結果。
每次解密時,都應指定用於執行“最新”加密操作的相同密鑰。 所以:
Encrypt Encrypt Decrypt Decrypt
with B with A with A with B
Plain text -> encrypted I -> encrypted II -> encrypted I -> plain text
我還建議,在同一時間執行這些操作的一個聲明,而不是從下往上由於在單個語句做的一切閱讀,就會使人們更方便明白發生了什么事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.