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

如何用JavaScript crypto.subtle解密Java AES-GCM加密字符串?

浏览器端AES-GCM解密Java加密内容的正确实现

先明确这类场景的核心匹配点:Java端用同一字符串生成密钥和IV(字节级完全一致)、AES-GCM模式默认16字节认证标签、加密结果是「密文+标签」拼接后转Base64输出。下面是对应能正常解密的浏览器JS代码,以及你遇到OperationError的常见原因:

核心解密函数

async function decryptAesGcm(encryptedBase64, keyIvString) {
  // 把Base64加密串转成字节数组
  const encryptedBytes = Uint8Array.from(atob(encryptedBase64), c => c.charCodeAt(0));
  
  // 拆分密文和认证标签(GCM默认标签长度16字节)
  const tagLength = 16;
  const ciphertext = encryptedBytes.slice(0, encryptedBytes.length - tagLength);
  const tag = encryptedBytes.slice(encryptedBytes.length - tagLength);
  
  // 把密钥/IV字符串转成UTF-8字节(和Java端编码保持一致)
  const keyBytes = new TextEncoder().encode(keyIvString);
  
  // 导入AES密钥(GCM模式用raw格式)
  const key = await crypto.subtle.importKey(
    'raw',
    keyBytes,
    { name: 'AES-GCM' },
    false,
    ['decrypt']
  );
  
  // 生成和Java端完全一致的IV
  const iv = new TextEncoder().encode(keyIvString);
  
  // 执行解密,必须传入认证标签
  const decryptedBuffer = await crypto.subtle.decrypt(
    {
      name: 'AES-GCM',
      iv: iv,
      tag: tag
    },
    key,
    ciphertext
  );
  
  // 转成明文字符串
  return new TextDecoder().decode(decryptedBuffer);
}

你遇到OperationError的常见原因

  • 密钥长度不合法:AES密钥必须是16/24/32字节(对应128/192/256位),如果你的密钥字符串转字节后长度不符合,JS会直接报错。比如Java端可能默认用字符串的全部字节当密钥,但JS的crypto.subtle不接受非标准长度的AES密钥,这时候要确认Java端是否做了截取/补全,或者换合法长度的密钥字符串。
  • IV或编码不匹配:确保Java端和JS端的字符串转字节用的是同一编码(比如Java要指定StandardCharsets.UTF_8,别用默认平台编码),且IV的字节数组完全一致。
  • 认证标签拆分错误:Java的cipher.doFinal()返回的字节数组是「密文+标签」,如果JS没拆分直接解密,或者拆分长度不对,就会触发认证失败的OperationError。

示例调用

// 替换成Java加密后的Base64串和你的密钥/IV字符串
decryptAesGcm("xxxEncryptedBase64xxx", "yourKeyIvString")
  .then(plaintext => console.log("解密结果:", plaintext))
  .catch(err => console.error("解密失败:", err));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 01:25:15