如何在Node.js中实现自定义填充的加密解密(兼容Java AES/CBC/ISO10126Padding)
Node.js 实现 AES/CBC/ISO10126Padding 解密
Java 的 ISO10126Padding 填充规则为:填充字节的最后一位表示填充长度(范围 1-16,因 AES 块大小为 16 字节),前面的填充字节为随机值。Node.js 的 crypto 模块原生不支持该填充模式,需手动处理填充移除,具体实现如下:
const crypto = require('crypto'); function decryptAesCbcIso10126(encryptedData, key, iv) { // 统一转换为Buffer(编码需和Java加密时的传输/存储编码一致,比如base64/hex) const encryptedBuffer = Buffer.isBuffer(encryptedData) ? encryptedData : Buffer.from(encryptedData, 'base64'); const keyBuffer = Buffer.isBuffer(key) ? key : Buffer.from(key, 'utf8'); // 密钥编码需与Java侧保持一致 const ivBuffer = Buffer.isBuffer(iv) ? iv : Buffer.from(iv, 'base64'); // IV必须和Java加密时完全相同 // 创建解密实例,禁用自动填充,手动处理ISO10126Padding const decipher = crypto.createDecipheriv( 'aes-128-cbc', // 密钥长度128/192/256对应aes-xxx-cbc,需和Java侧一致 keyBuffer, ivBuffer ); decipher.setAutoPadding(false); // 执行解密 let decrypted = decipher.update(encryptedBuffer); decrypted = Buffer.concat([decrypted, decipher.final()]); // 手动移除ISO10126Padding:取最后一个字节作为填充长度 const paddingLength = decrypted[decrypted.length - 1]; // 可选:验证填充长度合法性,避免篡改导致异常 if (paddingLength < 1 || paddingLength > 16) { throw new Error('Invalid padding length'); } // 截取掉填充部分 const plaintextBuffer = decrypted.slice(0, decrypted.length - paddingLength); // 返回明文(编码需和Java侧明文编码一致,比如utf8) return plaintextBuffer.toString('utf8'); }
关键注意事项
- 密钥长度匹配:若 Java 侧使用 256 位 AES 密钥,需将算法改为
'aes-256-cbc',以此类推。 - IV 一致性:CBC 模式的 IV 必须与加密时完全相同,通常加密后会将 IV 附加在密文头部或单独传递,解密时需先分离出 IV 和密文。
- 编码统一:密文、密钥、IV 的编码(如 Base64、UTF-8)需和 Java 加密时的处理逻辑完全一致。
内容的提问来源于stack exchange,提问作者Digvijay Rathore
相关产品推荐
相关产品推荐

