AES GCM 实现与 Java 中的身份验证标记

2022-09-03 12:52:07

我在我的Android项目中使用AES GCM身份验证,它工作正常。但是,当它与openssl API生成标记相比时,身份验证标记会遇到一些问题。请在下面找到java代码:

SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
byte[] iv = generateRandomIV();
IvParameterSpec ivspec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec);
int outputLength = cipher.getOutputSize(data.length); // Prepare output buffer
byte[] output = new byte[outputLength];
int outputOffset = cipher.update(data, 0, data.length, output, 0);// Produce cipher text
outputOffset += cipher.doFinal(output, outputOffset);

我在iOS中使用openssl,并使用以下代码生成身份验证标签

NSMutableData* tag = [NSMutableData dataWithLength:tagSize];
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, [tag length], [tag mutableBytes])

在java或充气城堡中,无法获得打开返回的确切身份验证标签,您可以帮助我解决此问题吗?谢谢


答案 1

不幸的是,在Java中标签被添加到密文的末尾。您可以使用以下命令配置大小(以位为单位,使用8的倍数) - 否则默认为128位的完整大小。因此,如果您真的想,可以使用来抓取标签。GCMParameterSpecArrays.copyOfRange(ciphertext, ciphertext.length - (tagSize / Byte.SIZE), ciphertext.length)

不幸的是,因为标签不必放在最后,并且它搞乱了GCM解密的在线性质 - 需要内部缓冲而不是能够直接返回明文。另一方面,标签在解密期间自动验证。


答案 2

推荐