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

AES-GCM 128位密钥JS解密认证错误问题求助

问题分析与修复

你的JS解密方法出现认证失败的问题,核心是数据处理流程和编码转换错误导致的,以下是具体问题点和修复方案:

核心错误点

  1. 不必要的Base64二次转换
    你将enc(Buffer类型的密文)转成Base64字符串后再传给decipher.update,这会导致数据被错误编码,直接传入Buffer即可。

  2. 解密调用的参数设置错误
    虽然你正确拆分了密文和认证标签,但update方法的参数类型和编码设置有误,应该直接传入密文Buffer,不需要指定'base64'编码。

  3. 潜在的算法与密钥一致性问题

    • 必须确保ALGO常量值为'aes-128-gcm',与Java的"AES/GCM/NoPadding"完全匹配。
    • 确保JS中的key是从加密密钥字符串按UTF-8编码转换而来,和Java的encryptionKey.getBytes(StandardCharsets.UTF_8)保持一致。

修复后的JS代码

const crypto = require('crypto');

// 确保ALGO和key的定义与Java逻辑一致
const ALGO = 'aes-128-gcm';
const key = Buffer.from('你的实际加密密钥', 'utf8'); // 替换为真实密钥

const decrypt = (encData) => {
  const encryptedBuffer = Buffer.from(encData, 'base64');

  // 提取IV长度(4字节大端序,与Java的ByteBuffer.getInt()逻辑一致)
  const ivLength = encryptedBuffer.readUInt32BE(0);

  // 提取IV
  const iv = encryptedBuffer.slice(4, 4 + ivLength);

  // 拆分密文和认证标签:密文是IV后数据去掉最后16字节,标签为最后16字节
  const cipherText = encryptedBuffer.slice(4 + ivLength, encryptedBuffer.length - 16);
  const authTag = encryptedBuffer.slice(encryptedBuffer.length - 16);

  // 创建解密实例
  const decipher = crypto.createDecipheriv(ALGO, key, iv);
  decipher.setAuthTag(authTag);

  // 直接传入Buffer解密,无额外编码转换
  let decrypted = decipher.update(cipherText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);

  // 转成UTF-8字符串返回,与Java的new String(decryptedBytes)逻辑一致
  return decrypted.toString('utf8');
};

module.exports = { decrypt };

关键验证点

  • 调试时打印ivLength,确认值为12(与Java代码中的12字节IV对应)。
  • 检查密钥的UTF-8编码是否和Java完全一致,避免因编码差异导致密钥不匹配。
  • 解密过程中不要对密文Buffer做任何额外编码转换,直接传入update方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 22:16:09