You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AES/CBC/PKCS5Padding加密JSON字符串解密时抛出IllegalBlockSizeException

问题分析与解决方案

这个异常的核心原因是你在加密过程中非法截断了Base64编码后的密文,又在解密时强行补全==,这种操作彻底破坏了Base64编码的完整性。只有当原始Base64字符串末尾恰好有两个=时才能正常工作,而当加密的内容(比如JSON字符串)导致Base64编码后没有后缀=时,就会导致解密时Base64解码出的字节长度不符合AES/CBC的块大小要求(必须是16的倍数),从而抛出IllegalBlockSizeException。

具体错误点

看你的encrypt方法:

String code = Base64.getEncoder().encodeToString(encrypted);
return salt + code.substring(0, code.length() - 2) + iv;

你无条件截断了Base64字符串的最后两个字符,然后在decrypt方法中强行补回==:

String base = message.substring(32, message.length() - 32) + "==";

但Base64的后缀=是用来补位的,只有当原始字节数不是3的倍数时才会出现,数量可能是1个、2个,甚至没有。比如:

  • 当加密后的字节数是16(如"Hello World"加密后):Base64编码后长度为22,末尾有两个=,截断后补回==刚好正确。
  • 当加密后的字节数是24(比如JSON字符串加密后):Base64编码后长度为32,没有后缀=,截断后补回==会导致Base64解码出的字节数比实际密文少,自然无法满足AES的块大小要求。

修正方案

完全去掉对Base64字符串的截断和补全操作,直接拼接salt、完整的Base64密文、iv即可——因为salt和iv的长度是固定的(都是32位十六进制字符串),解密时可以准确拆分:

修正后的encrypt方法

public static String encrypt(String password, String message) throws Exception {
    String salt = random(16);
    String iv = random(16);
    SecretKey key = generateKey(salt, password);
    byte[] encrypted = doFinal(Cipher.ENCRYPT_MODE, key, iv, message.getBytes("UTF-8"));
    String code = Base64.getEncoder().encodeToString(encrypted);
    // 直接拼接salt、完整Base64密文、iv
    return salt + code + iv;
}

修正后的decrypt方法

public static String decrypt(String password, String message) throws Exception {
    String salt = message.substring(0, 32);
    String iv = message.substring(message.length() - 32);
    // 提取中间完整的Base64密文
    String base = message.substring(32, message.length() - 32);
    SecretKey key = generateKey(salt, password);
    byte[] decrypted = doFinal(Cipher.DECRYPT_MODE, key, iv, Base64.getDecoder().decode(base));
    return new String(decrypted, "UTF-8");
}

额外优化建议

  • 你的HEX数组中有大小写不一致的问题:{'0', '1', ..., 'A', 'b', 'c', 'D', 'e', 'F'},建议统一为大写或小写,虽然Character.digit方法不区分大小写,但统一风格更规范。
  • random方法中每次创建新的SecureRandom实例,建议复用一个全局实例以提高效率。

验证

修正后,无论是普通字符串还是JSON格式字符串,加密和解密都能正常运行,不会再抛出块大小异常。

内容的提问来源于stack exchange,提问作者Felix Gaebler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:08:18