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

使用Java Crypto库无法匹配AES-GCM规范测试向量问题排查

问题排查与修正

你的核心问题大概率出在**stringToByteArray方法的实现**以及对Java AES-GCM输出结构的理解上,以下是具体分析和解决步骤:

1. 最可能的错误:stringToByteArray生成的不是全零字节数组

你假设stringToByteArray("0", 12)会生成12个0x00(全零)字节,但如果这个方法的逻辑是重复字符串"0"再转成字节,那实际生成的是12个0x30(ASCII字符'0'的十六进制值)。这会导致IV、密钥、AAD全部偏离测试向量的要求,只有最简单的无AAD、无明文的测试用例可能巧合匹配,一旦加入AAD就必然出错。

正确生成全零字节数组的方式应该是直接初始化:

// 生成length个0x00字节的数组
byte[] getZeroBytes(int length) {
    return new byte[length];
}

把测试用例里的stringToByteArray("0", N)替换成这个方法,比如:

GCMParameterSpec parameterSpec = new GCMParameterSpec(128, getZeroBytes(12));
SecretKeySpec secretKey = new SecretKeySpec(getZeroBytes(16), "AES");
byte[] aad = getZeroBytes(16);

2. 确认Java AES-GCM的输出结构

Java的Cipher.doFinal()返回的结果是密文 + 认证标签的拼接字节数组(GCM标签长度由GCMParameterSpec指定,这里是128位即16字节)。如果测试向量里的密文和标签是分开给出的,你需要把返回的cipherText拆分后分别对比:

  • 若明文长度为0(比如你的测试用例),则cipherText就是16字节的标签,直接和规范里的标签对比即可;
  • 若有明文,前明文长度字节是密文,后16字节是标签。

3. 验证AAD的处理逻辑

你的测试用例2中updateAAD的调用时机是正确的(在init之后、doFinal之前),但要确保没有在调用updateAAD后意外重置Cipher状态(比如再次调用init)。

修正以上两点后,应该就能匹配GCM规范中的测试向量了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:25:17