如何修改CryptoJS代码匹配node:crypto的createCipher加密结果?
问题描述
我有两段加密代码,一段基于Node.js的node:crypto模块createCipher接口实现,另一段尝试用CryptoJS生成相同加密结果,但两者输出不一致:
Node.js crypto 代码及输出:
const dataText = 'Hello'; const crypto = require('node:crypto'); const c = crypto.createCipher( 'aes-128-ecb', '2C8E29E736CB9514DD93C4D111244990' ); const r = c.update( dataText, 'utf-8', 'hex' ) + c.final( 'hex' ); console.log(r); // 输出:8a78f5302082a5e59aa5d28a1453cba1
CryptoJS 代码及输出:
const CryptoJS = require('crypto-js'); const encrypted = CryptoJS.AES.encrypt(dataText, '2C8E29E736CB9514DD93C4D111244990', { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).ciphertext.toString(CryptoJS.enc.Hex); console.log(encrypted); // 输出:f1b3424bb507a6e6185c1cf91527634d
需要修改第二段代码,使其加密结果与第一段匹配。
差异原因
- Node.js的
createCipher(已废弃接口)默认会对传入的密码执行MD5哈希,取前16字节(AES-128要求的密钥长度)作为加密密钥,无盐值处理。 - CryptoJS的
AES.encrypt若直接传入字符串密码,默认使用带随机盐值的EVP_BytesToKey算法生成密钥,和createCipher的密钥生成逻辑完全不同,导致结果不一致。
修改后的CryptoJS代码
要让CryptoJS和createCipher行为对齐,需手动模拟createCipher的密钥生成逻辑:
const dataText = 'Hello'; const CryptoJS = require('crypto-js'); // 1. 对密码执行MD5哈希,取前16字节(32位十六进制字符)作为AES-128密钥 const password = '2C8E29E736CB9514DD93C4D111244990'; const md5Hash = CryptoJS.MD5(password); const key = CryptoJS.enc.Hex.parse(md5Hash.toString(CryptoJS.enc.Hex).substring(0, 32)); // 2. 使用生成的密钥加密,ECB模式无需IV,显式指定避免默认生成 const encrypted = CryptoJS.AES.encrypt(dataText, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7, iv: '' }).ciphertext.toString(CryptoJS.enc.Hex); console.log(encrypted); // 输出:8a78f5302082a5e59aa5d28a1453cba1
额外提示
createCipher是Node.js已废弃的API,官方推荐使用createCipheriv手动指定密钥和IV,避免默认行为带来的安全隐患。如果是新项目,建议统一改用更安全的密钥管理方式,避免依赖废弃接口的默认逻辑。
内容的提问来源于stack exchange,提问作者bjornd
相关产品推荐
相关产品推荐

