【问题标题】:AES GCM implementation with authentication Tag in Java使用 Java 中的身份验证标签的 AES GCM 实现
【发布时间】:2014-07-14 21:24:12
【问题描述】:

我在我的 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 返回的确切身份验证标签,您能帮我解决这个问题吗?谢谢

【问题讨论】:

  • 你能澄清一下确切的问题吗?您需要配置标签长度还是要从密码中获取标签值?
  • 感谢 Oleg Estekhin。我正在尝试从密码中获取与 openssl 生成的标签相同的标签值。

标签: java android ios encryption aes-gcm


【解决方案1】:

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

不幸的是,标签没有放在最后,而且它搞乱了 GCM 的在线特性解密 - 需要内部缓冲而不是能够直接返回明文。另一方面,在解密过程中会自动验证标签。

【讨论】:

  • 我自己刚刚发现,AES/GCM 密码会保持不断增长的内部缓冲区,迟早会超过 Java 内存堆空间,以进行真正的大型解密操作。进行解密的密码将在调用 update() 期间写入 0 个字节,最后, doFinal() 输出所有解码的缓冲字节。这在很多方面都是不幸的。例如,Cipher.update(ByteBuffer, ByteBuffer) 要求目标缓冲区至少具有 Cipher.getOutputSize() 的容量,否则将引发 ShortBufferException。 Cipher.getOutputSize() 不断增加... [见下一条评论]
  • ... 报告的所需大小(随着内部缓冲区的增长)迫使我的应用程序也分配越来越大的目标 ByteBuffers,尽管 Cipher.update() 从未将一个字节写入分配的 ByteBuffers :'( 我认为这里的解决方案是在直接内存或磁盘上将文件拆分为 1 mb 块,然后在整个过程完成后将这些块修补在一起。我不是加密人,但你说当前的 Java 设计是有缺陷的。如果可以用另一种方式制作,那肯定是我自己的业余经验证明的。[见下一条评论]
  • 但是!如果我错了,请纠正我 - 我必须是 - 不是这样 MAC 是所有输入字节的哈希吗?那么实现必须“记住”所有字节才能计算 MAC?这可以解释为什么在这种情况下将 MAC 或“身份验证标签”放在密文的末尾并解释内部缓冲?如果你愿意,请详细说明这个问题,因为它对我很重要,可能还有很多其他人。谢谢猫头鹰!你太棒了。
  • 尝试使用充气城堡提供程序代码。如果我没记错的话,它应该只缓冲最大标签大小。你应该只使用 MAC验证后的明文,但是GCM内部使用CTR,在使用之前应该很容易存储明文。
猜你喜欢
  • 2013-07-17
  • 2020-05-29
  • 2016-08-24
  • 1970-01-01
  • 2018-08-20
  • 2015-10-29
  • 2017-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多