问题
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:
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.
来源:https://stackoverflow.com/questions/64505267/java-aes-gcm-nopadding-encryption-does-not-increment-the-counter-of-the-iv-after