前端用AES加密后端解不开,是不是密钥处理有问题?

南宫红娟 阅读 4

我在前端用 CryptoJS 做 AES 加密,传给后端 Java 服务,但后端一直报错解密失败。我确认了加密模式是 CBC,填充是 PKCS7,但还是不行。

密钥我是直接用字符串 'mySecretKey123',没做任何转换。是不是这里出问题了?后端说他们用的是十六进制或 Base64 的密钥格式。

const encrypted = CryptoJS.AES.encrypt('hello', 'mySecretKey123', {
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
}).toString();
我来解答 赞 3 收藏
二维码
手机扫码查看
1 条解答
东方邦安
问题找到了,你前端直接把字符串当密钥用,但 CryptoJS 内部会把这个字符串当作密码短语来派生密钥,生成的结果和后端直接用原始密钥完全对不上。

解决方案:前后端都用同一个原始密钥

前端代码改成这样:

// 把字符串转成 CryptoJS 的 WordArray
const key = CryptoJS.enc.Utf8.parse('mySecretKey123'); // 128位密钥,16字节
const iv = CryptoJS.enc.Utf8.parse('1234567890123456'); // 16字节IV

const encrypted = CryptoJS.AES.encrypt('hello', key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();


关键点:

1. 密钥必须转成 WordArray,CryptoJS.enc.Utf8.parse() 是效率最高的方式
2. CBC 模式需要显式传入 IV,不能让库自己生成,否则前后端 IV 不一致解密必败
3. 你的密钥 'mySecretKey123' 是 16 字符,刚好 16 字节,用 AES-128。如果密钥长度不是 16/24/32,需要补齐或截断

后端 Java 那边确认两件事:

- 密钥用 UTF-8 编码转字节数组,16字节
- IV 也是 UTF-8 转字节,16字节
- 填充用 PKCS5Padding(Java 里没 PKCS7,实际是一样的)

如果后端用的是 Hex 或 Base64 编码的密钥,那前端也要对应处理:

// 密钥是 Base64 的情况
const key = CryptoJS.enc.Base64.parse('bXlTZWNyZXRLZXkxMjM=');

// 密钥是 Hex 的情况
const key = CryptoJS.enc.Hex.parse('6d795365637265744b6579313233');


核心就一句话:确保前后端用的是完全相同的原始字节序列,别让 CryptoJS 自动派生密钥。
点赞
2026-03-12 13:04