Java AES/GCM/NoPadding加密在调用doFinal方法后没有递增IV的计数器。

huangapple go评论79阅读模式
英文:

Java AES/GCM/NoPadding encryption does not increment the counter of the IV after doFinal

问题

当我使用默认的AES/GCM算法初始化Cipher对象时,它具有一个随机的12字节IV,但在调用doFinal后,前4个字节不会递增,而会抛出java.lang.IllegalStateException: Cannot re-use same key and IV for multiple encryptions异常。

SecretKey secretKey = ...

final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

byte[] iv1 = encCipher.getIV();
byte[] ctext = encCipher.doFinal("a".getBytes());

cipher.update("b".getBytes());
byte[] iv2 = encCipher.getIV();
ctext = encCipher.doFinal();
英文:

When I initialize a Cipher object with the default AES/GCM algorithm, it has a reandom 12 bytes IV but the first 4 byte does not get incremented ater doFinal is called and throws the java.lang.IllegalStateException: Cannot re-use same key and IV for multiple encryptions exception.

SecretKey secretKey = ...

final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);

byte[] iv1 = encCipher.getIV();
byte[] ctext = encCipher.doFinal("a".getBytes());
      
cipher.update("b".getBytes());
byte[] iv2 = encCipher.getIV();
ctext = encCipher.doFinal();

答案1

得分: 5

> java.lang.IllegalStateException: 无法为多次加密重复使用相同的密钥和 IV 异常。

这是为了您的保护,希望在至少在相同的 Cipher 对象下使用时库保持这种行为。

AES-GCM 内部对加密使用 AES 的 CTR 模式,对于 CTR 模式,重复使用(密钥,IV)对会导致通过 crib-dragging 造成灾难性的机密性失败。

AES-GCM 使用 12 字节的 IV/nonce,其余部分用于计数器。前两个计数器值是保留的,因此您最多可以加密 2^32-2 个块,这相当于 2^39-256 位,在单个(IV,密钥)对下可以达到约 68GB。

12 字节的 nonce 是 NIST 800-38d 的标准。如果提供的 nonce 不等于 12 字节,那么它将会被 使用 GHASH 进行处理,之后大小将变为 12 字节。

如果 len(IV) = 96 则
    J_0 = IV || 0^{31}1
否则
    J_0 = GHASH_H(IV || 0^{s+64} || len(IV_64))

不建议使用 NIST 建议的基于计数器的 IV 生成方式,因为它会使其变得随机。此外,由于 GHASH 调用,加密会变慢一些。

>当我使用默认的 AES/GCM 算法初始化 Cipher 对象时,它有一个随机的 12 字节 IV,但前 4 字节不会递增。

这是预期的行为。对应的计数器再次被设置为零。您是否希望在文件比计数器支持的更大时继续?分割文件并创建链式结构

  • 此外,请参阅正确使用 AES-GCM 的规则是什么?

  • 每当标签不正确时,不要使用明文。

  • 存在一种 AES-GCM-SIV 模式,消除了(IV,密钥)对的误用。它只会泄露相同消息在相同 IV 和密钥下再次发送的事实。

  • TLS 实际上对于每个记录都使用一个新的(密钥,IV)对,最多为 2^14 字节,这可以防止内存填充攻击。考虑一下,如果您将内存用于解密 68GB,则会发现标签不正确。对于服务器来说,这是一个不错的 DOS 攻击点。

  • 在可用的情况下,使用 ChaCha20-Poly1305 比使用 AES-GCM 更容易。尽管如此,它仍然存在(IV,密钥)重用的问题。

  • 存在一种 XChaCha20,它使用 192 位的 nonce 和 64 位的计数器。它可以安全地处理非常大的数据大小和随机 nonce。

英文:

> java.lang.IllegalStateException: Cannot re-use same key and IV for multiple encryptions exception.

This is for your protection and hopefully, the library keeps this behavior at least when used under the same Cipher object.

The AES-GCM internally uses AES in CTR mode for encryption and for CTR mode the reuse of the (key,IV) pair is a catastrophic failure of the confidentiality by the crib-dragging.

The AES-GCM uses 12-byte IV/nonce and the remaining is used for the counter. The first two counter values are reserved so you can encrypt at most 2^32-2 blocks and that makes 2^39-256 bits and makes around 68-GB under a single (IV, key) pair.

The 12-byte nonce is standard by the NIST 800-38d. If you supply a nonce not equal to 12-byte, then it will be processed with GHASH and the size will be 12-byte after that.

if len(IV) = 96 then 
    J_0 = IV || 0^{31}1
else 
    J_0=GHASH_H(IV||0^{s+64}||len(IV_64))

It is not advised if you use counter-based IV generation as suggested by NIST because it will make it random. Also, it will make your encryption a bit slower due to the GHASH call.

>When I initialize a Cipher object with the default AES/GCM algorithm, it has a reandom 12 bytes IV but the first 4 byte does not get incremented

This is what expected. The counterpart is set to zero again. Do you want to continue where it is left since your file is larger than the counter supports? Divide the file and make chain.

  • Additionally, see What are the rules for using AES-GCM correctly?
  • Whenever a tag is incorrect, don't use the plaintext at all.
  • There is an AES-GCM-SIV mode that eliminates the (IV,key) pair misuse. It only leaks that the same message is sent again under the same IV and key.
  • TLS actually uses a new (key,IV) pair per record which has at most 2^14-byte this prevents memory fill attacks. Consider you spend your memory on decryption of 68-GB then you have seen that the tag is incorrect. Nice DOS attack point for servers.
  • Using ChaCha20-Poly1305 much easier than AES-GCM where available. It has still (IV,key)-reuse problem, though.
  • There is an XChaCha20 that uses a 192-bit nonce and 64-bit counter. That can handle very large data sizes and random nonces securely.

huangapple
  • 本文由 发表于 2020年10月24日 02:09:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/64505267.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定