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

时间:2014-05-26 06:59:54

标签: java android ios encryption aes-gcm

我在我的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或bouncy castle中,无法获得openssl返回的确切身份验证标记,是否可以帮助我解决此问题。感谢

1 个答案:

答案 0 :(得分:5)

在Java中,标签是,遗憾的是在密文的末尾添加了。您可以使用GCMParameterSpec配置大小(以位为单位,使用8的倍数)。因此,如果您真的想要,可以使用Arrays.copyOfRange(ciphertext, ciphertext.length - (tagSize / Byte.SIZE), ciphertext.length)获取它。

很遗憾,因为标签没有放在最后,这会使GCM 解密的在线性质变得混乱 - 需要内部缓冲而不是能够直接返回明文。另一方面,标签在解密期间自动验证。