Node.js使用Crypto库做AES-128-CBC加密与.NET结果不一致如何解决
问题根源
- 你编写的Node.js代码没有拼接
cipher.update()返回的加密结果,仅取了cipher.final()的输出,导致加密结果不完整 - Node.js Crypto模块默认使用PKCS7填充,和.NET端指定的
PaddingMode.Zeros零填充规则不匹配
修正方案
Node.js Crypto没有内置零填充的配置项,你需要先关闭默认的自动填充,手动实现零填充逻辑,修正后的可运行代码如下:
const crypto = require('crypto'); const key = Buffer.from('00112233445566778899aabbccddeeff', 'hex'); const iv = Buffer.from('aabbccddeeff00112233445566778899', 'hex'); const plaintext = 'admin'; const aesBlockSize = 16; // AES算法块大小固定为16字节 // 手动实现ZeroPadding:将明文补至长度为块大小的整数倍,不足位补0 let plaintextBuffer = Buffer.from(plaintext, 'utf8'); const paddingLength = aesBlockSize - (plaintextBuffer.length % aesBlockSize); if (paddingLength > 0) { plaintextBuffer = Buffer.concat([plaintextBuffer, Buffer.alloc(paddingLength, 0x00)]); } // 创建加密实例,关闭默认PKCS7自动填充 const cipher = crypto.createCipheriv('aes-128-cbc', key, iv); cipher.setAutoPadding(false); // 拼接所有加密块的输出 const encryptedBuffer = Buffer.concat([cipher.update(plaintextBuffer), cipher.final()]); const encryptedBase64 = encryptedBuffer.toString('base64'); console.log(encryptedBase64); // 输出结果为 gE1twb8LV/44oO/6UKwwCg== 与.NET端完全一致
说明
cipher.setAutoPadding(false)的作用是关闭Node.js Crypto默认的PKCS7填充逻辑,让你手动补充的零填充生效- 零填充规则完全匹配.NET的
PaddingMode.Zeros:明文长度不是块大小整数倍时补0至整数倍,刚好为整数倍时不额外补块 - 必须拼接
cipher.update()和cipher.final()的返回值,因为AES是分块加密,两个方法分别返回不同块的加密结果,遗漏任何一部分都会导致输出错误
内容的提问来源于stack exchange,提问作者Scopperloit
相关产品推荐
相关产品推荐

