如何将DES加密Java代码转为JavaScript?解决密钥长度报错问题
DES/CBC/PKCS5Padding加密:Java转JavaScript的正确实现及问题解决
问题背景
需要将一段实现DES/CBC/PKCS5Padding加密的Java代码转换为JavaScript代码,但转换后运行出现ERR_CRYPTO_INVALID_KEYLEN错误,核心问题是密钥长度不符合DES算法要求。
原Java代码
public static String getSignature(String skey, String iv, String data) throws Exception { IvParameterSpec Ⅳ = new IvParameterSpec(iv.getBytes("utf-8")); DESKeySpec desKey = new DESKeySpec(skey.getBytes("utf-8")); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(desKey); Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, Ⅳ); byte[] databyte = cipher.doFinal(data.getBytes("utf-8")); return new String(Base64.getEncoder().encode(databyte)); }
自行尝试的JavaScript代码(存在问题)
function getSignature( skey, iv, data, ) { const IV = Buffer.from(ivString, 'utf-8'); // 笔误:ivString应为iv const desKey = Buffer.from(skey, 'utf-8'); const cipher = crypto.createCipheriv('des-cbc', desKey, IV); let encrypted = cipher.update(data, 'utf-8', 'base64'); encrypted += cipher.final('base64'); return encrypted; }
错误原因
- 笔误问题:代码中误用
ivString而非参数iv,会导致IV读取错误。 - 密钥处理逻辑缺失:Java中
SecretKeyFactory.generateSecret(desKey)会自动将输入的密钥字节数组截断为前8个字节(DES密钥固定为8字节),而Node.js的crypto.createCipheriv要求DES密钥必须严格为8字节,若传入的密钥字节数超过8会直接抛出密钥长度错误。
正确的JavaScript实现
const crypto = require('crypto'); // 引入Node.js内置crypto模块 function getSignature(skey, iv, data) { // 处理IV:与Java保持一致,转UTF-8字节 const ivBuffer = Buffer.from(iv, 'utf-8'); // 处理密钥:模拟Java逻辑,取UTF-8字节的前8个作为DES密钥 const keyBuffer = Buffer.from(skey, 'utf-8').slice(0, 8); // 初始化Cipher:des-cbc对应Java的DES/CBC,默认使用PKCS5Padding const cipher = crypto.createCipheriv('des-cbc', keyBuffer, ivBuffer); // 加密并输出Base64格式结果 let encrypted = cipher.update(data, 'utf-8', 'base64'); encrypted += cipher.final('base64'); return encrypted; }
关键说明
- 密钥处理:DES算法的密钥长度固定为8字节,Java的
DESKeySpec和SecretKeyFactory会自动截取输入密钥的前8个字节,JS中需手动用slice(0, 8)实现相同逻辑。 - 填充方式:Node.js的
des-cbc默认使用PKCS5Padding,与Java的DES/CBC/PKCS5Padding完全匹配,无需额外配置。 - IV要求:CBC模式的IV长度必须与块大小一致(DES块大小为8字节),需确保传入的iv转UTF-8后是8字节,否则Java和JS都会报错。
内容的提问来源于stack exchange,提问作者bbnn
相关产品推荐
相关产品推荐

