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

博主红梅 阅读 66

我在用 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());

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

我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
UX柯豫
UX柯豫 Lv1
这其实不是问题,而是CryptoJS的工作原理。每次加密时它都会在密文中加入一个随机的salt值,所以即使明文、密钥和IV都一样,最终输出也会不同。

要解决这个问题很简单,直接用 getCiphertext() 方法获取纯密文部分就行。不过我建议你换个思路,在WordPress里做这种加密操作,不如直接用成熟的插件来处理。

如果你非要自己写代码,可以这样改:

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.ciphertext.toString()); // 这样就能得到稳定的输出了


说实话,在WordPress上折腾这种底层加密挺累的,建议还是找现成方案。要是真需要加密传输数据,还不如考虑HTTPS这种更简单直接的办法。
点赞
2026-03-31 14:08
明哲 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