What Is an Initialization Vector (IV)

Understand what an Initialization Vector (IV) is, why it is critical for encryption security, and what happens when IVs are reused. Covers IV requirements for AES-GCM, AES-CBC, and ChaCha20.

Encryption Concepts

Detailed Explanation

Initialization Vectors (IVs) in Encryption

An Initialization Vector (IV) — also called a nonce (number used once) — is a random or unique value used alongside the encryption key to ensure that encrypting the same plaintext twice produces different ciphertexts.

Why IVs Are Necessary

Without an IV, a deterministic cipher would always produce the same ciphertext for the same plaintext and key. This leaks information:

Without IV:
  Encrypt("Attack at dawn", Key) ──▶ always "x7f9a2..."
  Encrypt("Attack at dawn", Key) ──▶ always "x7f9a2..."  // Same!

With IV:
  Encrypt("Attack at dawn", Key, IV₁) ──▶ "x7f9a2..."
  Encrypt("Attack at dawn", Key, IV₂) ──▶ "k3m8p1..."  // Different!

An attacker observing network traffic could detect repeated messages, even without decrypting them. The IV eliminates this pattern.

IV Requirements by Mode

Different encryption modes have different IV requirements:

AES-GCM:

  • Size: 96 bits (12 bytes) recommended
  • Requirement: Must be unique (never reused with the same key)
  • Generation: Random is acceptable; counter-based is also fine
  • Reuse consequence: Catastrophic — exposes authentication key, enables forgery and plaintext recovery

AES-CBC:

  • Size: 128 bits (16 bytes) (same as block size)
  • Requirement: Must be unpredictable (random, not just unique)
  • Generation: Must be cryptographically random
  • Reuse consequence: Leaks whether two plaintexts share a common prefix

ChaCha20-Poly1305:

  • Size: 96 bits (12 bytes) standard, or 192 bits for XChaCha20
  • Requirement: Must be unique
  • Generation: Random or counter-based
  • XChaCha20's 192-bit nonce makes random generation safe even for high-volume encryption

Generating IVs Correctly

// Correct: cryptographically random IV
const iv = crypto.getRandomValues(new Uint8Array(12)); // For AES-GCM

// Correct: counter-based IV (for sequential message encryption)
let counter = 0n;
function nextIv() {
  const iv = new Uint8Array(12);
  new DataView(iv.buffer).setBigUint64(4, counter++);
  return iv;
}

// WRONG: predictable IV
const iv = new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,1]); // Never hardcode!

IV vs Nonce vs Salt

These terms are related but distinct:

  • IV — General term for the initialization value used in block cipher modes
  • Nonce — "Number used once" — emphasizes the uniqueness requirement (used in GCM, ChaCha20)
  • Salt — Random value used in key derivation (PBKDF2, bcrypt) and hashing — does not need to be secret

Storage and Transmission

The IV is not secret. It is typically prepended to the ciphertext or stored alongside it. The recipient needs the IV to decrypt, so it must be transmitted or stored in the clear.

Use Case

Understanding IVs is critical for any developer implementing encryption. Common mistakes include using a fixed IV (making encryption deterministic), reusing IVs with the same key in AES-GCM (catastrophic security failure), or using a predictable IV in AES-CBC (enabling chosen-plaintext attacks). Security code reviews frequently catch IV-related bugs, making this knowledge essential for both developers and reviewers.

Try It — Encryption Playground

Open full tool