NodeJS中AES-256-CBC解密出现ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH错误排查
ERR_OSSL_WRONG_FINAL_BLOCK_LENGTH错误成因与修复方案
错误成因
这个错误的核心原因是加密解密时使用的key/iv长度不符合AES-256-CBC的标准要求:
- AES-256算法要求key必须是32字节(256位)长度
- CBC模式要求iv必须是16字节(128位)长度
如果你的key或iv长度不达标,Node.js的crypto模块会自动对其进行截断或补全处理,这会导致加密后的密文块结构异常,解密时就会触发块长度不匹配的错误。虽然表面上加密解密能执行成功,但底层的块校验已经失败,所以错误被抛出。
另外,如果解密时传入的base64密文存在损坏(比如截断、额外字符),也可能触发该错误,但结合你描述的“功能正常执行”,key/iv不规范是更大概率的原因。
修复方案
1. 规范key的生成与长度
确保key是严格的32字节长度,推荐从密码派生标准key(避免直接用短字符串作为key):
import crypto from 'crypto'; // 从用户密码派生32字节的key(盐值需妥善保存,解密时要用到) const password = 'your-user-password'; const salt = crypto.randomBytes(16); // 生成随机盐值 const key = crypto.scryptSync(password, salt, 32); // 派生32字节key
2. 使用随机且标准长度的iv
CBC模式的iv需要是随机值(不能固定),且必须是16字节。加密时要将iv和密文一起返回,解密时拆分出来使用:
修改加密函数:
export function encrypt(plainString:string) { const iv = crypto.randomBytes(16); // 生成16字节随机iv const cipher = crypto.createCipheriv("aes-256-cbc", key, iv); let encrypted = Buffer.concat([cipher.update(Buffer.from(plainString, "utf8")), cipher.final()]); // 将iv和密文用分隔符拼接后返回 return `${iv.toString('base64')}:${encrypted.toString("base64")}`; }
修改解密函数:
export function decrypt(combinedString:string) { // 拆分iv和密文 const [ivBase64, encryptedBase64] = combinedString.split(':'); const iv = Buffer.from(ivBase64, 'base64'); const decipher = crypto.createDecipheriv("aes-256-cbc", key, iv); const deciphered = Buffer.concat([decipher.update(Buffer.from(encryptedBase64, "base64")), decipher.final()]); return deciphered.toString("utf8"); }
3. 校验密文完整性
确保密文在存储、传输过程中没有被修改或截断,避免解密时传入无效的base64字符串。
内容的提问来源于stack exchange,提问作者jennie788
相关产品推荐
相关产品推荐

