为什么用AES加密后前端和后端的密文结果不一致?

上官怡轩 阅读 307

我在给表单数据做AES加密时遇到奇怪的问题。用前端库加密后的密文,后端用同样的密钥解密总报错。之前用jsencrypt试过RSA没问题,换成AES-256-CBC后就乱了。

前端代码是这样的:


const CryptoJS = require("crypto-js");
let ciphertext = CryptoJS.AES.encrypt('测试数据', 'secret-key-123', {
  mode: CryptoJS.mode.CBC,
  padding: CryptoJS.pad.Pkcs7
}).ciphertext.toString();

后端用Node.js的crypto模块:


const cipher = crypto.createCipheriv('aes-256-cbc', 'secret-key-123', iv);
let encrypted = cipher.update(data, 'utf8', 'hex') + cipher.final('hex');

明明都用了CBC模式,为什么密文完全不一样?是不是库的默认参数有差异?试过调整padding和编码方式都没用,求大神指条明路…

我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
a'ゞ光远
问题出在两个地方:密钥和IV。前端CryptoJS会自动把字符串密钥转成32字节,而后端直接用了原始字符串;另外前端默认生成随机IV,你得手动指定。

改成这样:

前端代码:

const CryptoJS = require("crypto-js");
let key = CryptoJS.enc.Utf8.parse('secret-key-123'); // 转成32字节
let iv = CryptoJS.enc.Utf8.parse('1234567890123456'); // 固定IV
let ciphertext = CryptoJS.AES.encrypt('测试数据', key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).ciphertext.toString(CryptoJS.enc.Hex);


后端代码:

const crypto = require('crypto');
const key = Buffer.from('secret-key-123'); // 自动补齐到32字节
const iv = Buffer.from('1234567890123456');
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update('测试数据', 'utf8', 'hex') + cipher.final('hex');


记得两边都用固定IV,生产环境要把IV和密文一起传输,别忘了处理好编码问题。
点赞 3
2026-02-15 23:06