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

Java使用AES/CBC/PKCS5Padding加解密字符串解密结果为随机乱码

问题原因

AES/CBC模式解密要求必须使用和加密时完全一致的16字节IV(初始化向量),你的代码存在两个核心错误直接导致解密乱码:

  • 解密时没有使用加密生成的IV,而是重新调用new SecureRandom().nextBytes(iv)生成了全新的随机IV,和加密用的IV完全不匹配。
  • 加密返回结果仅包含密文的Base64编码,没有把加密时生成的IV一并返回,解密端根本无法获取正确的IV。

你观察到的相同输入每次加密结果不同是正常表现——CBC模式本来就要求每次加密使用不同的随机IV,避免相同明文生成相同密文的安全风险,只要解密时能拿到对应IV就可以正常还原明文。

修复方法

调整加解密逻辑,在加密时把IV和密文拼接后再编码返回,解密时先从解码后的内容中拆分出IV和真实密文,再执行解密操作,不要在解密阶段重新生成IV。

修复后加密代码

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(key.toCharArray(), "salt".getBytes(), 65536, 256);
SecretKey secret =new SecretKeySpec(factory.generateSecret(spec).getEncoded(),"AES");

byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
IvParameterSpec ivp = new IvParameterSpec(iv);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret, ivp);

byte[] encryptedText = cipher.doFinal(input.getBytes("UTF-8"));
// 拼接IV与密文:固定前16字节为IV,后续字节为真实密文
byte[] combined = new byte[iv.length + encryptedText.length];
System.arraycopy(iv, 0, combined, 0, iv.length);
System.arraycopy(encryptedText, 0, combined, iv.length, encryptedText.length);
return Base64.getEncoder().encodeToString(combined);

修复后解密代码

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(key.toCharArray(), "salt".getBytes(), 65536, 256);
SecretKey secret =new SecretKeySpec(factory.generateSecret(spec).getEncoded(),"AES");

byte[] combined = Base64.getDecoder().decode(input);
// 拆分出前16字节作为IV,剩余部分为真实密文
byte[] iv = new byte[16];
byte[] realEncrypted = new byte[combined.length - 16];
System.arraycopy(combined, 0, iv, 0, 16);
System.arraycopy(combined, 16, realEncrypted, 0, realEncrypted.length);

IvParameterSpec ivp = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, ivp);

byte[] decryptedtext = cipher.doFinal(realEncrypted);
return new String(decryptedtext, "UTF-8");
注意事项
  • IV不需要保密,和密文明文拼接存储/传输不会带来安全风险。
  • 代码中硬编码固定salt仅适合本地调试,生产环境建议每次加密使用独立随机salt,和IV、密文一同存储即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:25:04