← Back to Blog

AES Encryption Modes: ECB, CBC and GCM Explained with Diagrams

Start with a common encryption misconception

"If it uses AES, it is secure"—that sentence only answers half the question. AES is a block cipher: it defines the transform for a single fixed-size block. How you split arbitrary-length plaintext into blocks, how blocks influence each other, and how you prevent tampering are answered by the mode of operation. Choose the wrong mode and AES protection drops considerably.

This article walks the three most-used modes visually and gives selection advice you can apply directly.

Understand the block first

AES processes 16-byte blocks. Longer plaintext is split into 16-byte chunks; the final short block gets PKCS7 padding.

plaintext:  [12-byte region]                → pad 4 bytes
actual:     [12-byte region][\x04\x04\x04\x04]  → 16 total

A full block always adds one extra padding block (\x10×16) so decryption can always tell real data from padding.

ECB: blocks are fully independent

block1 ──AES──▶ c1
block2 ──AES──▶ c2     (blocks do not influence each other)
block3 ──AES──▶ c3

Identical plaintext blocks → identical ciphertext blocks. That is the fatal flaw: repeated patterns survive encryption. Don't use ECB by default; it suits only a single fixed-length, unpredictable block.

CBC: chain the previous block into the next

      IV(random)      c1              c2
        │             │               │
block1 ─┴─∈⊕────────► AES ──►┐  block2─┴─∈⊕─► AES ──►

CBC XORs each plaintext block with the previous ciphertext block before encrypting, forming a chain:

  • IV's role: the random initialization vector serves as the predecessor of the first block;
  • IV rules: fresh and random every time, never reused; prepend it to the ciphertext;
  • Drawbacks: encryption must run serially (no parallelism), and one corrupted ciphertext block corrupts the following plaintext block too.

GCM: encrypt and authenticate together

GCM encrypts in CTR counter mode (parallel, no padding) and computes an auth tag over the output:

nonce ──▶ counter(1) ─▶ keystream ∈⊕ block1 ─▶ c1 ─┐
nonce ──▶ counter(2) ─▶ keystream ∈⊕ block2 ─▶ c2 ─┼──▶ GMAC tag
                                                      AAD ─┘
  • Output = nonce ‖ ciphertext ‖ tag; the tag detects any tampering;
  • The 96-bit nonce is random and unique, never reused under the same key;
  • Default in TLS 1.3 and mainstream libraries (OpenSSL, WebCrypto, Go, .NET).

Mode quick reference

Property ECB CBC GCM
Confidentiality
Integrity/anti-tamper ✘ (add HMAC) ✔ (auth tag built-in)
Padding PKCS7 PKCS7 None (stream)
Parallelizable
Random IV/nonce Not needed Required Required
Caveat Leaks patterns Serial; easy to botch HMAC Use a vetted implementation

Common pitfalls checklist

  1. ECB on variable-length data → leaks structure; switch to GCM.
  2. CBC with reused/hardcoded IV → common-prefix leak; random IV each time, prepended.
  3. Encryption without authentication → ciphertext can be flipped and still decrypt; GCM authenticates.
  4. GCM nonce reuse → keystream reuse, catastrophic; one unique nonce per key.
  5. Hardcoded key in source → defeats even the strongest cipher; manage keys securely and separately.

Try it yourself

Pick an encryption library (WebCrypto's AES-GCM works in the browser) and encrypt the same pattern-heavy text twice with CBC and GCM. You will see CBC yields different ciphertext due to a different IV, demonstrating its purpose. Now flip any byte in a GCM ciphertext and tag verification fails—that is the value of authenticated encryption.

Remember one line: default to AES-256-GCM; make IV/nonce random and unique; store the ciphertext together with its nonce and tag.

Frequently Asked Questions

Why is ECB mode insecure?

ECB encrypts each block independently, so identical plaintext blocks yield identical ciphertext blocks. For images, configs or databases with repeated patterns, the encrypted output still reveals structure at the visual or statistical level (think of the famous encrypted-penguin image whose silhouette is still clearly visible). It hides neither patterns nor provides chaining, so it should never be the default—except for a single fixed-length, unpredictable block (e.g. wrapping one key).

Why must the CBC IV be random and unique?

CBC XORs each plaintext block with the previous ciphertext block before encrypting, creating a chain. The first block has no predecessor, so the IV serves that role—and it must be freshly random, never reused, for every encryption (usually 16 bytes). Reusing an IV under the same key leaks that two plaintexts share a common prefix, which an attacker can exploit to recover that prefix. The correct practice is to prepend the public IV to the ciphertext and store/transmit it together, never hardcode a constant.

Why is GCM called authenticated encryption?

Beyond encryption, GCM computes a GMAC authentication tag over the ciphertext and AAD so tampering is detected. Unlike CBC/ECB which only provide confidentiality, GCM provides both confidentiality and integrity, runs in counter mode (no padding, parallelizable, high throughput) and is the default AES-GCM in TLS 1.3 and mainstream libraries. The cost: nonce/IV reuse is more catastrophic, and some implementations expose timing side-channel risks via hardware acceleration—so use vetted implementations.

Which AES mode should I actually choose?

One main line: **default to AES-256-GCM**—it gives both confidentiality and integrity, needs no padding and performs well. Only fall back to AES-256-CBC + HMAC if your library lacks GCM (and build encrypt-then-MAC yourself, which is error-prone). Conventions: for CBC always generate a random IV and prepend it; for GCM always generate a random 96-bit nonce and store it with the tag alongside the ciphertext. Never use ECB for variable-length data; equally important is how you securely manage/store the key.

← Back to Blog