Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
866 views
in Technique[技术] by (71.8m points)

android - Java AES/GCM/NoPadding encryption does not increment the counter of the IV after 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();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...