You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 19:32:51