使用AES-128-CBC解密时出现Invalid key length错误,原因是什么?
解决AES-128-CBC解密时的"Invalid key length"错误
这个问题的核心是你传入的密钥长度不符合AES-128算法的硬性要求,咱们一步步拆解原因和解决方案:
为什么会触发这个错误?
AES-128-CBC明确要求密钥长度是128位,也就是16字节。但你的代码对密钥的处理流程,导致最终传入的密钥长度严重超标:
- 你定义的
key是一个44字符的base64字符串,用Buffer.from(key, 'base64')解码后得到的是33字节的Buffer(base64编码规则是每4个字符对应3字节,44/4=11组,11*3=33字节)。 - 你又把这个33字节的Buffer转成了hex字符串(每个字节对应2个hex字符,最终是66个字符),把这个hex字符串作为密钥传给
createDecipheriv时,Node.js的crypto模块会默认按UTF-8编码把它转成Buffer,长度远超过AES-128要求的16字节,自然就触发了"Invalid key length"错误。
另外还有个关键问题:解密时的IV必须和加密时使用的IV完全一致,你现在用crypto.randomBytes(16)生成随机IV,这是没法正确解密的,得换成加密时的那个IV才行。
怎么修复?
第一步:确认正确的密钥来源
首先要核对你的密钥是否正确:AES-128的密钥是16字节,对应的base64编码应该是24个字符左右(因为16字节转base64是16*4/3≈21.33,填充后是24个字符)。你现在的44字符base64字符串明显不是标准的AES-128密钥,要么是密钥本身有误,要么是你多拼接了额外内容。
第二步:正确处理密钥格式
如果确认这个base64字符串是你要使用的密钥(比如后端返回的包含额外信息的字符串),你需要确保最终传入的密钥是16字节:
const crypto = require('crypto'); // 你的原始base64密钥 var key = 'DoCKvdLslTuB4y3EZlKate7XMottHski1LmyqJHvUhs'+'='; // 注意:这里必须替换成加密时使用的IV,不能随机生成! var iv = Buffer.from('这里放加密时用的IV', 'base64'); // 解码base64密钥,截取前16字节(仅示例,若密钥本身有误需先修正) var keyBuffer = Buffer.from(key, 'base64').slice(0, 16); // 传入Buffer格式的密钥,确保长度是16字节 var decipher = crypto.createDecipheriv('aes-128-cbc', keyBuffer, iv);
如果你的base64字符串就是正确的AES-128密钥(解码后刚好16字节),那直接用解码后的Buffer即可,不用转hex:
const crypto = require('crypto'); var key = '正确的16字节密钥对应的base64字符串'; var iv = Buffer.from('加密时的IV', 'base64'); var keyBuffer = Buffer.from(key, 'base64'); console.log(keyBuffer.length); // 这里输出16才是正确的 var decipher = crypto.createDecipheriv('aes-128-cbc', keyBuffer, iv);
内容的提问来源于stack exchange,提问作者周雪静
相关产品推荐
相关产品推荐

