与Cipher合作时,我观察到以下内容。
加密码:
Cipher aes = Cipher.getInstance("AES"); aes.init(Cipher.ENCRYPT_MODE, generateKey()); byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
解密代码:
Cipher aes = Cipher.getInstance("AES"); aes.init(Cipher.DECRYPT_MODE, generateKey()); byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
运行Decrypt代码时,出现IllegalBlockSizeException(输入长度必须为16的倍数)。
但是如果我将解密代码更改为
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); //I am passing the padding too aes.init(Cipher.DECRYPT_MODE, generateKey()); byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
它工作正常。我知道这是有规律的algorithm/mode/padding。所以我以为是因为我没有提到填充。所以我尝试在加密过程中提供模式和填充,
algorithm/mode/padding
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");//Gave padding during encryption too aes.init(Cipher.ENCRYPT_MODE, generateKey()); byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding"); aes.init(Cipher.DECRYPT_MODE, generateKey()); byte[] ciphertext = aes.doFinal(rawPassword.getBytes());
但是它失败,并带有IllegalBlockSizeException。
原因是什么,为什么会发生异常以及其下到底发生了什么。如果有人可以帮忙?提前致谢
更新
看起来问题出在我正在加密和解密的字符串上。因为,即使我说的代码有效,也不总是有效。我基本上是在加密UUID(例如:8e7307a2-ef01-4d7d-b854-e81ce152bbf6)。它适用于某些字符串,不适用于某些其他字符串。
加密的字符串的长度为64,可被16整除。是的,我正在同一台计算机上运行它。
密钥生成方法:
private Key generateKey() throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA"); String passphrase = "blahbl blahbla blah"; digest.update(passphrase.getBytes()); return new SecretKeySpec(digest.digest(), 0, 16, "AES"); }
在解密过程中,如果输入数据不是块大小的倍数(AES为16字节),则 只能 获得一个IllegalBlockSizeException。
IllegalBlockSizeException
如果密钥或数据无效(但长度正确),则会得到a,BadPaddingException因为PKCS#5填充在明文中是错误的。有时填充会偶然显示正确,您也不例外。
BadPaddingException
注意:我建议您始终指定填充和模式。如果您不这样做,那么如果提供程序更改了默认设置,您可能会感到惊讶。Sun提供商AFAIK转换"AES"为"AES/ECB/PKCS5Padding"。
"AES"
"AES/ECB/PKCS5Padding"