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

如何使用CryptoJS解密window.subtle.crypto的AES-GCM加密数据

适配解决方法

Web Crypto API和CryptoJS的AES-GCM实现参数存在格式差异,按以下步骤调整即可完成解密:

核心适配点

  • 密钥处理:Web Crypto导出的JWK字段k是Base64URL编码的原始密钥,需要先解码为CryptoJS支持的WordArray格式,CryptoJS不识别Web Crypto生成的CryptoKey对象
  • 密文拆分:Web Crypto加密返回的ArrayBuffer是「密文 + 16字节GCM认证标签」的拼接结果,CryptoJS解密时需要将密文和标签拆分后单独传入
  • 格式统一:IV、密文、标签都需要从Uint8Array/ArrayBuffer转换为WordArray类型
  • 算法配置:解密时显式指定GCM模式,传入拆分后的认证标签

完整可运行代码

const text = "This is an encrypted message";
// ArrayBuffer转WordArray工具方法
const buf2WordArray = (buf) => {
  const uint8 = new Uint8Array(buf);
  return CryptoJS.lib.WordArray.create(uint8, uint8.length);
}

const generateKey = async () => {
  const key = await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 128 }, true, ["encrypt", "decrypt"]);
  const key_exported = await window.crypto.subtle.exportKey("jwk", key);
  return key_exported.k;
}

const printCurrent = async () => {
  let kkey = await generateKey();
  // 先把JWK的base64url格式密钥转成CryptoJS能用的WordArray
  const cryptoJSKey = CryptoJS.enc.Base64.parse(kkey.replace(/-/g, '+').replace(/_/g, '/'));
  const iv = new Uint8Array(12); // 测试用固定IV,生产环境需随机生成
  const cryptoJSIv = buf2WordArray(iv);
  
  const importedKey = await window.crypto.subtle.importKey(
    "jwk",
    {
      k: kkey,
      alg: "A128GCM",
      ext: true,
      key_ops: ["encrypt", "decrypt"],
      kty: "oct",
    },
    { name: "AES-GCM", length: 128 },
    false,
    ["encrypt", "decrypt"]
  );
  
  const encryptedBuf = await window.crypto.subtle.encrypt(
    { name: "AES-GCM", iv: iv }, 
    importedKey, 
    new TextEncoder().encode(JSON.stringify(text))
  );
  // 拆分密文和GCM标签:最后16字节是标签,前面是密文
  const encryptedUint8 = new Uint8Array(encryptedBuf);
  const ciphertext = buf2WordArray(encryptedUint8.slice(0, -16));
  const authTag = buf2WordArray(encryptedUint8.slice(-16));
  
  // 调用CryptoJS解密
  const decrypted = CryptoJS.AES.decrypt(
    { ciphertext: ciphertext },
    cryptoJSKey,
    {
      iv: cryptoJSIv,
      mode: CryptoJS.mode.GCM,
      padding: CryptoJS.pad.NoPadding,
      authTag: authTag
    }
  );
  console.log("cryptojs解密结果:", decrypted.toString(CryptoJS.enc.Utf8));
}
printCurrent();

注意事项

测试用固定全0IV仅适用于调试,生产环境必须使用随机生成的12字节IV,且IV需要和密文一起存储传递才能正常解密。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:15:04