Java中AES加密文本解密失败问题排查与解决
解决Java AES解密时的BadPaddingException问题
看你的代码和报错信息,问题很明确——你在解密的时候把十六进制格式的加密文本直接转成字节数组了,这根本不是加密后原始的字节数据!
你加密后用bytesToHex把加密字节转成了十六进制字符串,但解密时却用encrypted.getBytes()来获取字节,这相当于把字符串的每个字符转成对应的字节(比如"7C"会变成两个字节:0x37和0x43),而不是把十六进制字符串解析回原来的加密字节(0x7C)。这就导致解密时的数据完全不对,自然触发了BadPaddingException。
错误的关键代码片段
原来的解密方法里,这一行是问题核心:
byte[] bytePlainText = aesCipher.doFinal(encrypted.getBytes()); // 这里逻辑错误!
修正后的完整代码
解决办法很简单:添加一个和bytesToHex对应的方法,把十六进制字符串转回字节数组,解密时调用这个方法即可:
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.xml.bind.DatatypeConverter; public class aesencrypt { public static void main(String[] args) throws Exception { String plainText = "Hello World"; System.out.println("Original Text:" + plainText); SecretKey secKey = getSecretEncryptionKey(); System.out.println("AES Key (Hex Form):"+bytesToHex(secKey.getEncoded())); String encryptedText = bytesToHex(encryptText(plainText, secKey)); System.out.println("Encrypted Text (Hex Form):"+encryptedText); String decryptedText = decryptText(encryptedText, secKey); System.out.println("Decrypted Text:"+decryptedText); } public static SecretKey getSecretEncryptionKey() throws Exception{ KeyGenerator generator = KeyGenerator.getInstance("AES"); generator.init(128); SecretKey secKey = generator.generateKey(); return secKey; } public static byte[] encryptText(String plainText,SecretKey secKey) throws Exception{ Cipher aesCipher = Cipher.getInstance("AES"); aesCipher.init(Cipher.ENCRYPT_MODE, secKey); byte[] byteCipherText = aesCipher.doFinal(plainText.getBytes()); return byteCipherText; } public static String decryptText(String encrypted, SecretKey secKey) throws Exception { Cipher aesCipher = Cipher.getInstance("AES"); aesCipher.init(Cipher.DECRYPT_MODE, secKey); byte[] bytePlainText = aesCipher.doFinal(hexToByte(encrypted)); // 这里完成了修正 return new String(bytePlainText); } private static String bytesToHex(byte[] hash) { return DatatypeConverter.printHexBinary(hash); } // 新增的十六进制字符串转字节数组方法 private static byte[] hexToByte(String txt) { return DatatypeConverter.parseHexBinary(txt); } }
修正后的运行结果
Original Text:Hello World
AES Key (Hex Form):84526F32BEDDBEA5BFBCDE241AD9BBA2
Encrypted Text (Hex Form):25378032E5F52575B7CEF311D45F00BD
Decrypted Text:Hello World
总结来说,核心问题就是十六进制字符串和加密字节数组的转换逻辑不匹配,加密时把字节转成十六进制字符串存储,解密时必须把十六进制字符串解析回原始字节数组,而不是直接取字符串的字节。
内容的提问来源于stack exchange,提问作者Wraith




