使用错误密钥进行Java AES解密

时间:2013-10-04 03:01:19

标签: java encryption aes badpaddingexception

我已经编写了一个简单的Java AES加密和解密,如下所示(用于学习目的):

//Encryption 
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");  
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
 String encryptedString = Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes()));
return encryptedString;

//Decryption
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
String decryptedString = new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt)));
return decryptedString;

密码密钥是一个可变长度的字符串,我MD5哈希该字符串以获得128位密钥。

我可以使用相同的密钥成功加密和解密数据。但如果我用错误的密钥解密数据,我得到以下例外:

javax.crypto.BadPaddingException: Given final block not properly padded

实际上我所期望的是,错误的密钥解密产生了错误的字节,但没有像上面那样抛出异常,因为如果产生错误的字节,黑客可能不知道解密是否正确。如果像上面那样抛出异常,蛮力的输出将变得更容易确定。

那么,我的代码会发生什么?

修改

我想我在这里弄错了。黑客可能不会使用我的程序来解密。因此,对于AES,如果一个人解密失败,他会知道解密失败但不是因为我认为从解密中获取错误的字节?这太糟糕了......

1 个答案:

答案 0 :(得分:5)

您的代码没有任何问题(尽管您可以通过为字符和字节之间的转换指定编码而不是依赖于平台编码来使其更加健壮)。填充具有某种格式,因此可以在解密后将其删除。使用错误的密钥解密时,填充也会出现乱码,无法删除。这会导致异常。

在大多数情况下,攻击者会知道他的错误密钥不仅仅是因为填充。数据字节通常也有一些结构(例如某种文件格式),或者在你的情况下,他会检测不寻常的字符或无效的字符编码。例如,如果以UTF-8为例,并非每个二进制字符串都是有效的UTF-8编码。