You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动