If there is one mistake that has broken more encryption systems than any other, it is IV reuse. It is the crypto equivalent of reusing a one-time pad. It sounds harmless, and it is incredibly easy to do by accident, but it can completely destroy the security of your encryption.
Let's talk about what an IV is, why it exists, and what exactly goes wrong when you reuse it.
What an IV Is
IV stands for initialization vector. It is a value that is fed into the encryption algorithm alongside the key and the plaintext. The key is secret and stays the same across encryptions. The IV is not secret and changes with every encryption.
The purpose of the IV is to make each encryption unique. Without an IV, encrypting the same plaintext with the same key always produces the same ciphertext. With an IV, the same plaintext with the same key but a different IV produces a completely different ciphertext.
Think of it this way. The key determines the encryption algorithm's behavior. The IV randomizes the starting point. Even if an attacker knows the IV (and they can, because it is not secret), they cannot derive the key from it. The IV just ensures that the encryption output is different each time, even for identical inputs.
Why IVs Exist
To understand why IVs are necessary, consider what happens without one. Suppose you are encrypting a series of messages with AES and the same key. Message 1 is "Hello" and message 2 is also "Hello". Without an IV, both produce the exact same ciphertext.
An attacker observing the ciphertexts can see that messages 1 and 2 are identical, even without decrypting them. This is already a leak of information. In a real system, this pattern leakage can be devastating.
Consider a database where each row has an encrypted "status" field. If the status is "active" or "inactive", and you encrypt without an IV, all "active" rows will have the same ciphertext. An attacker can see the distribution of statuses without decrypting anything. They can also see when a status changes, because the ciphertext changes from one known value to another known value.
The IV prevents this. With a unique IV per encryption, "active" encrypted in row 1 produces a completely different ciphertext from "active" encrypted in row 2. The attacker sees random-looking values and cannot tell which rows have the same status.
What Happens When You Reuse an IV
Now for the dangerous part. What happens if you reuse the same IV with the same key for two different encryptions?
In GCM mode, the encryption works by generating a keystream from the key and IV, then XORing the plaintext with the keystream. If you reuse the IV, you reuse the keystream. Now you have:
- Ciphertext 1 = Plaintext 1 XOR Keystream - Ciphertext 2 = Plaintext 2 XOR Keystream
If the attacker XORs the two ciphertexts together, the keystreams cancel out:
- Ciphertext 1 XOR Ciphertext 2 = Plaintext 1 XOR Plaintext 2
The attacker now has the XOR of the two plaintexts. This is called a two-time pad, and it is breakable. If the attacker knows or can guess one of the plaintexts (which is common, since many messages have known headers or formats), they can recover the other plaintext immediately.
This is not a theoretical attack. It is how the Venona project broke Soviet encryption in the 1940s. It is how researchers broke WEP (WiFi encryption) in the 2000s. It is one of the most reliably exploited vulnerabilities in the history of cryptography.
Why GCM Makes IV Reuse Catastrophic
With GCM, IV reuse is even worse than with other modes. GCM computes an authentication tag using a hash key (called H) that is derived from the key. The tag computation depends on the IV. If two encryptions use the same IV, the attacker can use the relationship between the two tags to recover H.
Once the attacker has H, they can forge authentication tags for any message. This means they can create valid-looking encrypted messages that the recipient will accept as authentic. The integrity protection that GCM provides is completely defeated.
This is not a subtle attack. Researchers have demonstrated that a single IV reuse in GCM allows practical tag forgery. The more reuses, the easier it gets. With a handful of reuses, the attack is trivial.
This is why GCM implementations are so careful about IV generation. The Web Crypto API generates a random IV for each encryption call. If you are implementing GCM yourself, you must do the same.
How to Get IV Generation Right
The rules are simple:
**Use a cryptographically secure random number generator.** In the browser, that is crypto.getRandomValues. In Node.js, it is crypto.randomBytes. Never use Math.random or a regular PRNG for IV generation.
**Generate a fresh IV for every encryption.** Do not reuse IVs. Do not increment them unless you are using a deterministic construction that is specifically designed for it (and if you are not sure, you are not). Random IVs are the safe default.
**Do not keep a counter.** Some implementations use a counter as the IV to avoid the cost of generating random bytes. This works in theory but is fragile. If the counter resets (due to a restart, a bug, or a clock issue), you get IV reuse. Random IVs have no such failure mode.
**Store the IV alongside the ciphertext.** The IV is not secret. You need it for decryption, so store it or transmit it with the ciphertext. A common format is IV || ciphertext || tag.
**Use the right IV size.** For GCM, the standard IV size is 12 bytes (96 bits). This is large enough that the probability of a random collision is astronomically small (you would need to encrypt about 2^48 messages before a 50% chance of collision). Do not use shorter IVs.
The Good News
If you are using a well-designed library or API, IV generation is handled for you. The Web Crypto API generates a random IV automatically. Our AES text encryptor generates a fresh IV for every encryption. You do not need to think about it.
The danger is when you are implementing encryption from scratch or using a low-level API that expects you to provide the IV. In those cases, the rules above are critical. Get the IV right and your encryption is secure. Get it wrong and it is broken, no matter how strong your key or algorithm.
For a deeper understanding of the encryption mode that uses these IVs, read our AES-256-GCM explained post.