Encrypting the same data twice with the same key should not produce identical ciphertext. An initialization vector (IV) is a non-secret value combined with the encryption input to vary that transformation and hide repeated patterns. section 5.2.1 section 5.7
The IV is not a password or secret key. It can usually be stored alongside the ciphertext so decryption can recover it, but it must be fresh and never reused with the same key. In cryptographic terminology, a value used only once is a nonce. section 5.2.1 section 5.2.3
Use an IV with these practical rules:
- Generate it with a cryptographically secure random-number generator such as Java's SecureRandom; java.util.Random is not suitable. section 5.3
- For AES-GCM, use a fresh 96-bit (12-byte) IV for every encryption and never repeat an IV with the same key. section 5.5.2
- Treat IV reuse in GCM as a serious failure: attackers may learn plaintext information or forge messages. section 5.2.3 section 5.6
AES-GCM output
A Java AES-GCM encryption routine generates a random 12-byte IV, initializes AES/GCM/NoPadding with the key and IV, encrypts the plaintext, and returns the IV followed by the ciphertext and authentication tag. Decryption reads the IV from the beginning, verifies the tag, and rejects tampered data. section 5.3 section 5.6
Figure 5.6 AES in GCM mode, shown as a black box that processes three inputs: plaintext, key, and IV. The algorithm outputs the IV (used in plaintext) followed by the ciphertext it computes and the authentication code generated by GCM mode. To decrypt, you provide four inputs: IV, ciphertext, key, and authentication code. The algorithm uses these inputs to verify the data’s integrity and recover the original plaintext.
Visualizes the IV, key, plaintext, ciphertext, and authentication code as inputs and outputs of AES-GCM. section 5.2.3
CBC uses an IV to prevent repeated ciphertext patterns but provides confidentiality only. GCM additionally provides integrity and authenticity, yet is fragile when IV generation, key management, or tag validation is mishandled. Prefer a well-tested library such as Tink instead of implementing these details manually. section 5.2.1 section 5.5.2


