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

Node.js解密Java AES密文报wrong final block length错误

报错核心信息

Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

错误产生原因

报错是Java加密端与Node.js解密端的逻辑、参数完全不匹配导致,核心问题有4个:

  • 算法与密钥长度不匹配:Java端取SHA-256哈希结果的前16字节作为AES密钥,16字节对应AES-128算法;但Node端错误使用了aes-256-ecb算法,该算法要求32字节长度密钥,参数完全不匹配。另外Java中Cipher.getInstance("AES")默认使用AES/ECB/PKCS5Padding工作模式,Node端ECB模式默认使用PKCS7填充,二者本身兼容,但必须匹配密钥长度。
  • 密钥截取逻辑无效:Node端虽然循环取了哈希值的前16字节存入key数组,但后续生成keyBuffer时直接传入了完整32字节的SHA-256结果,根本没有使用截取后的16字节密钥,密钥值和加密端完全不一致。
  • 密文解码方式错误:Java端使用URL安全Base64对密文做编码输出,但Node端错误将密文按十六进制(hex)格式转成Buffer,解码得到的二进制密文完全错误,长度不符合AES块对齐要求,直接触发块长度错误。
  • 废弃API使用风险:Node端使用的new Buffer()构造方法已经废弃,在高版本Node.js中会出现不可预期的类型转换问题。
修复方案

1. Java端优化(可选,避免默认参数歧义)

显式指定加密算法/模式/填充,不要依赖JDK默认实现,避免不同环境下的行为差异:

byte[] input = "data".getBytes();       
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] thedigest = md.digest("ENCRYPTION_KEY".getBytes("UTF-8"));
// 取前16字节,对应AES-128
SecretKeySpec skc = new SecretKeySpec(Arrays.copyOf(thedigest, 16), "AES");
// 显式指定算法/模式/填充
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skc);

byte[] cipherText = cipher.doFinal(input);
// URL安全Base64编码
String encryptData = Base64.getUrlEncoder().encodeToString(cipherText);
System.out.println("encryptString:.......... "+encryptData);

2. Node.js解密代码修正

对齐Java端所有逻辑参数:

const crypto = require('crypto');
// 密钥与Java端保持一致
const keyStr = "ENCRYPTION_KEY";
// 替换为Java端实际输出的URL安全Base64密文
const encryptedData = "替换为实际的Java加密输出密文";

// 1. 生成SHA-256哈希,截取前16字节作为AES-128密钥
const hashPwd = crypto.createHash('sha256').update(keyStr, 'utf8').digest();
const keyBuffer = Buffer.from(hashPwd.subarray(0, 16));

// 2. 转换URL安全Base64为标准Base64格式,补全缺失的填充符
let base64Str = encryptedData.replace(/-/g, '+').replace(/_/g, '/');
const padLen = (4 - (base64Str.length % 4)) % 4;
base64Str = base64Str.padEnd(base64Str.length + padLen, '=');
const cipherTxtBuffer = Buffer.from(base64Str, 'base64');

// 3. 创建AES-128-ECB解密器,ECB模式不需要IV,传null即可
const decipher = crypto.createDecipheriv('aes-128-ecb', keyBuffer, null);

// 4. 执行解密
const output = Buffer.concat([decipher.update(cipherTxtBuffer), decipher.final()]);
console.log("解密结果:", output.toString('utf8'));
额外注意事项
  • ECB模式安全性较低,固定密钥重复加密相同明文会得到相同密文,生产环境建议使用CBC/GCM等更安全的模式,搭配随机IV使用。
  • 直接对密钥做SHA-256哈希派生加密密钥的方式安全性不足,生产环境建议使用PBKDF2、Argon2等专业密钥派生算法。

内容的提问来源于stack exchange,提问作者Shik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:18:15