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

Node.js crypto aes-256-cbc解密报错:encoding参数无效问题排查

问题原因及修复方案

错误根源

1. 加密时的Buffer转换逻辑错误

原加密代码将cipher输出的hex字符串以默认的utf8编码转成Buffer,这会破坏原始加密数据的二进制结构。hex字符串的每个字符对应4位二进制,按utf8解析时,部分字符会被视为多字节字符,导致最终生成的Base64字符串还原后,hex字符串长度可能为奇数(如383),而hex编码要求字符串长度必须为偶数,因此触发解密错误。

2. 密钥和IV长度不符合AES-256-CBC要求

原代码通过digest('hex')后截取字符串的方式生成key和iv,得到的key仅为16字节(32个hex字符),但AES-256-CBC要求key必须是32字节(256位),这会导致加密算法实际使用的密钥长度不匹配,存在安全隐患。

修复后的代码

const crypto = require("crypto");

// 修正key和iv的生成:直接取哈希后的Buffer前N字节,满足AES-256-CBC的要求
const key = crypto
  .createHash('sha512')
  .update(process.env.AES_SECRET_KEY)
  .digest() // 得到64字节的Buffer
  .subarray(0, 32); // 取前32字节作为256位密钥

const encryptionIV = crypto
  .createHash('sha512')
  .update(process.env.AES_SECRET_IV)
  .digest()
  .subarray(0, 16); // 取前16字节作为IV

const method = 'aes-256-cbc'

// 加密数据:直接操作Buffer,避免hex字符串转码错误
exports.encryptData = (data) => {
  try {
    const cipher = crypto.createCipheriv(method, key, encryptionIV);
    // 拼接cipher输出的Buffer,直接转Base64
    const encryptedBuffer = Buffer.concat([
      cipher.update(data, 'utf8'),
      cipher.final()
    ]);
    return encryptedBuffer.toString('base64');
  } catch (error) {
    return undefined;
  }
}

// 解密数据:对应加密逻辑,直接解析Base64为Buffer后解密
exports.decryptData = (encryptedData) => {
  try {
    const buff = Buffer.from(encryptedData, 'base64');
    const decipher = crypto.createDecipheriv(method, key, encryptionIV);
    // 拼接decipher输出的Buffer,转utf8字符串
    const decryptedBuffer = Buffer.concat([
      decipher.update(buff),
      decipher.final()
    ]);
    return decryptedBuffer.toString('utf8');
  } catch (error) {
    return undefined;
  }
}

额外说明

  • 直接操作Buffer的方式比hex字符串中转更高效,且避免了编码转换带来的错误。
  • 确保process.env.AES_SECRET_KEY和process.env.AES_SECRET_IV是足够复杂的随机字符串,避免使用弱密钥。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:52:49