React中使用AES加密数据后后端无法解密怎么办?

Air-彦森 阅读 289

我在React项目里用crypto-js做了AES加密,但后端说收到的密文解密失败。我按照文档设置了CBC模式和pkcs5填充,测试时发现加密后的base64字符串总比预期的多两个等号,这正常吗?


import CryptoJS from 'crypto-js';

const encrypt = (text, key) => {
  const iv = CryptoJS.enc.Utf8.parse('1234567812345678');
  return CryptoJS.AES.encrypt(
    text,
    key,
    { 
      iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7 
    }
  ).toString();
};

useEffect(() => {
  const data = encrypt('测试数据', 'my-secret-key-16');
  console.log(data); // 输出: U2FsdGVkX1...
  // 发送到后端的POST请求
}, []);

我试过把key补全到16位,调整编码方式,但后端Java服务始终报错”pad block corrupted”。是不是前端加密时base64处理有问题?或者模式配置哪里不对?

我来解答 赞 30 收藏
二维码
手机扫码查看
2 条解答
 ___治博
你这个问题挺典型的,前后端AES加密解密踩坑多半是这几个地方:key、iv、编码、填充。复制这个,直接改你的代码就能用了。

问题出在 CryptoJS.enc.Utf8.parse 这个方法上,前端和后端对 key 和 iv 的处理方式不一致。Java 后端一般用的是 Hex 格式,而你这里是 Utf8,导致两边算出来的值不一样。

修改后的代码:

import CryptoJS from 'crypto-js';

const encrypt = (text, key) => {
const iv = CryptoJS.enc.Hex.parse('1234567812345678'); // 修改为 Hex.parse
const keyHex = CryptoJS.enc.Hex.parse(key); // 修改为 Hex.parse
return CryptoJS.AES.encrypt(
text,
keyHex,
{
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
).toString();
};

useEffect(() => {
const data = encrypt('测试数据', 'my-secret-key-16');
console.log(data); // 输出正确的密文
// 发送到后端的POST请求
}, []);


记得后端也要用同样的 key 和 iv,并且设置 CBC 模式和 PKCS5 填充。别忘了 key 和 iv 都得是 16 进制字符串,长度固定 16 位(128 位)。

最后,关于 Base64 的两个等号,这是正常的补位,不用管它,后端能正确解析就行。如果还有问题,就检查一下字符集是否一致,UTF-8 是标配。
点赞 12
2026-02-01 19:02
Air-慧慧
问题在于前端加密时使用的key和iv需要确保与后端一致,包括编码格式。CryptoJS默认会做一些特殊处理,你需要明确指定key和iv为16进制字符串。试试这样改:

const encrypt = (text, key) => {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const ivHex = CryptoJS.enc.Utf8.parse('1234567812345678');
return CryptoJS.AES.encrypt(text, keyHex, {
iv: ivHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).ciphertext.toString(CryptoJS.enc.Base64);
};

// 调用示例
const data = encrypt('测试数据', 'my-secret-key-16');
console.log(data);


重点是ciphertext部分单独转Base64,这样后端Java解密才不会报pad错误。记得确认后端用的也是相同参数。
点赞 4
2026-02-01 06:14