CryptoJS加密结果每次都不一样,怎么回事?

博主红梅 阅读 5

我在用 CryptoJS 做 AES 加密,但发现每次对相同明文加密出来的结果都不同,这让我没法做数据比对。明明密钥和 IV 都是固定的,按理说应该输出一致才对啊?

我试过这样写:

const key = CryptoJS.enc.Utf8.parse('1234567890123456');
const iv = CryptoJS.enc.Utf8.parse('1234567890123456');
const encrypted = CryptoJS.AES.encrypt('hello', key, { iv: iv });
console.log(encrypted.toString());

但每次刷新页面输出的密文都变,是不是哪里理解错了?

我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
明哲 Dev
这不是 bug,是 CryptoJS 的安全特性。

CryptoJS 的 AES 加密默认使用 OpenSSL 格式输出,这个格式会自动生成随机的 salt 和 IV,即使你手动传入了固定的 IV,它还是会生成随机 salt 放在密文前面。这就是为什么每次结果都不同。

你用的高级 API CryptoJS.AES.encrypt 封装了太多东西,底层帮你加了随机 salt。要实现确定性加密(每次结果相同),得用底层 API 跳过自动生成的 salt:

const key = CryptoJS.enc.Utf8.parse('1234567890123456');
const iv = CryptoJS.enc.Utf8.parse('1234567890123456');

const cipher = CryptoJS.algo.AES.createEncryptor(key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});

const encrypted = cipher.finalize('hello');
console.log(encrypted.toString());


这样每次输出的密文就一致了。

不过多说一句,随机 salt 是安全最佳实践,能防止彩虹表攻击。如果你做数据完整性校验或防篡改,应该用 HMAC 而不是靠密文比对。
点赞
2026-03-18 17:06