2

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();
5
  • 1
    And what is your question? What are you trying to accomplish? Commented Oct 23, 2020 at 18:15
  • Maybe I'm misusing the cipher. I don't understand why it uses the 12 byte IV instead of 16 if it does not increment. I have to encrypt a large file with the same 256bit key chunking it and incrementing the counter of the nonce automatically. Commented Oct 23, 2020 at 18:23
  • Why not use a random IV for each chunk? If the chunks are independent then you can use a different IV. If they are not, do the encryption once and chunk it afterwards Commented Oct 23, 2020 at 18:44
  • 1
    Kindly see this answer from @Maarten Bodewes to this topic: crypto.stackexchange.com/a/41610/50189. The IV/nonce length recommendation is 96 bit/12 byte is a) for compability with other programs and b) any other length require a new (internal) recalculating. Commented Oct 23, 2020 at 18:59
  • I cannot split after encryption because the ciphertext will be kept in memory until the end, in case of large file it will throw an exception because insufficient memory. Commented Oct 24, 2020 at 6:39

1 Answer 1

7

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.
Sign up to request clarification or add additional context in comments.

9 Comments

"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 I set the IV manually with GCMParameterSpec object, it is actually a 16byte IV not 12. I know that the IV must be used once so I tought that the cipjer object automatically increment the count part of the iv after submitting the cleartext for encryption. Would be fine if I input the (ciphertex+tag) to update the aad of next file segment ?
The ciphertext is too big for aad, it can be a number between 1 and 2^64. Because it is not processed yet!
Is your file too big?
Yes it is big. If i split it in 4mb part should be not a problem to pass it as authentication, should be?
How big is it? More than 68-GB in a phone? The aad can be at most 64-bit by the standard. Do you have to use AES-GCM?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.