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

使用Web Crypto解密AES-CBC时出现Uncaught (in promise) Error错误求助

AES-CBC解密报错的解决思路

核心问题分析

你的代码里有两个关键问题导致解密失败:

  • 密文转换方式错误:ciphertext是十六进制字符串,你用str2ab按字符编码转成ArrayBuffer,这会把每个十六进制字符(比如'1'、'0')当成单个字节处理,完全不符合AES解密要求的原始密文字节格式。
  • 缺少错误捕获:原代码没有处理Promise的异常分支,导致报错信息模糊,无法定位具体问题。

修正方案

  1. 替换十六进制转ArrayBuffer的函数
    实现专门的十六进制转字节数组的逻辑,替换原来处理密文的str2ab:

    function hex2ab(hexStr) {
      const buf = new ArrayBuffer(hexStr.length / 2);
      const bufView = new Uint8Array(buf);
      for (let i = 0; i < hexStr.length; i += 2) {
        bufView[i / 2] = parseInt(hexStr.substr(i, 2), 16);
      }
      return buf;
    }
    

    然后把ciphertext = str2ab(ciphertext);改成ciphertext = hex2ab(ciphertext);

  2. 添加错误捕获逻辑
    在Promise链末尾加上.catch,打印具体错误信息:

    window.crypto.subtle.importKey(/* ... */)
    .then(function(key) {
      return window.crypto.subtle.decrypt(/* ... */);
    })
    .then(function(plaintext) {
      console.log(new TextDecoder().decode(plaintext));
    })
    .catch(function(err) {
      console.error('解密失败:', err);
    });
    

完整修正后的代码

var key = 'aaaaaaaaaaaaaaaa'
var iv = 'bbbbbbbbbbbbbbbb';
var ciphertext = '10f42fd95857ed2775cfbc4b471bc213';

// 十六进制转ArrayBuffer
function hex2ab(hexStr) {
    const buf = new ArrayBuffer(hexStr.length / 2);
    const bufView = new Uint8Array(buf);
    for (let i = 0; i < hexStr.length; i += 2) {
        bufView[i / 2] = parseInt(hexStr.substr(i, 2), 16);
    }
    return buf;
}

// 普通字符串转ArrayBuffer(用于密钥和IV)
function str2ab(str) {
    const buf = new ArrayBuffer(str.length);
    const bufView = new Uint8Array(buf);
    for (let i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
}

key = new TextEncoder().encode(key);
iv = new TextEncoder().encode(iv);
ciphertext = hex2ab(ciphertext);

window.crypto.subtle.importKey(
    'raw',
    key,
    {
        name: 'AES-CBC'
    },
    true,
    ['decrypt']
).then(function(key) {
    return window.crypto.subtle.decrypt(
        {
            name: "AES-CBC",
            iv: iv
        },
        key,
        ciphertext
    );
}).then(function(plaintext) {
    console.log(new TextDecoder().decode(plaintext));
}).catch(function(err) {
    console.error('解密出错:', err);
});

额外说明

如果修正后仍报错,需要确认:

  • 密钥长度是否符合AES要求(16字节对应AES-128,你的密钥是16字节,没问题)
  • IV是否和加密时使用的完全一致(你的IV是16字节,符合AES-CBC要求)
  • 加密时使用的填充方式是否和Web Crypto默认的PKCS#7一致(Web Crypto API的AES-CBC默认使用PKCS#7填充,如果加密时用了其他填充方式,需要手动处理)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:55:00