AES-256-GCM Encryption: Authenticated Without Jargon
AES-256-GCM doesn't just hide your data — it detects tampering. Learn how authenticated encryption works, why GCM matters, and how to use it correctly.
Introduction
You encrypted your file. But did you also protect it from being silently modified?
Encryption hides content — but without authentication, an attacker can flip bits in the ciphertext and produce altered output that decrypts without error. You’d never know the file was tampered with. This is called a bit-flipping attack, and older encryption modes like AES-CBC are vulnerable to it (as well as to related padding oracle attacks, which leak plaintext through error responses). To understand how encryption modes differ, see our guide on encryption explained.
AES-256-GCM solves this by combining encryption and authentication into a single step. If anyone touches the ciphertext — even one bit — decryption fails loudly. This article explains exactly how it works and how to use it correctly.
What Is AES-256-GCM Encryption?
AES-256-GCM is an authenticated encryption with associated data (AEAD) algorithm. Let’s break that down:
- AES-256: The Advanced Encryption Standard with a 256-bit key. The cipher itself — the mathematical engine that scrambles data.
- GCM: Galois/Counter Mode. The operating mode that determines how AES processes data in blocks and, critically, how it generates an authentication tag.
- Authenticated: Every encrypted output includes a tag (16 bytes by default) that proves the ciphertext was created by someone with the correct key and hasn’t been modified since.
Think of it as a tamper-evident seal on a package. The encryption hides the contents; the authentication tag proves the seal hasn’t been broken.
How AES-256-GCM Works
AES-256-GCM performs two jobs simultaneously: encryption using CTR mode, and authentication using GHASH.
Step 1 — Counter Mode Encryption (CTR)
- A nonce (12 random bytes) and a counter are combined to create a keystream block.
- AES-256 encrypts that keystream block using your 256-bit key.
- The resulting keystream is XOR’d with your plaintext — producing ciphertext.
- The counter increments for each 16-byte block of data.
CTR mode turns AES — normally a block cipher — into a stream cipher. It’s fast, parallelizable, and requires no padding.
Step 2 — Authentication Tag (GHASH)
- The ciphertext from Step 1 is passed through a polynomial multiplication over a finite field (Galois field — the “G” in GCM).
- Any optional additional authenticated data (AAD) — like file metadata or headers — is also included in this calculation.
- The result is a 128-bit authentication tag appended to the ciphertext.
During decryption, the tag is verified before any plaintext is returned. If the tag doesn’t match, decryption aborts. The receiver learns nothing about the plaintext.
The Three Components of an AES-GCM Output
Every AES-GCM output contains three parts stored together: the encrypted data (ciphertext), a 16-byte authentication tag, and the 12-byte nonce. The nonce travels alongside the ciphertext in plaintext — it’s not sensitive, but it must be unique for every encryption with the same key.
If you want to see how the underlying AES cipher actually scrambles data — the substitution and permutation steps GCM builds on — this Computerphile explainer is the clearest short version:
AES-256-GCM performs encryption and authentication simultaneously. CTR mode generates the ciphertext while GHASH produces a 128-bit authentication tag that detects any tampering.
AES-256-GCM vs AES-256-CBC
| Attribute | AES-256-GCM | AES-256-CBC |
|---|---|---|
| Provides confidentiality | Yes | Yes |
| Detects tampering | Yes (authentication tag) | No |
| Parallelizable encryption | Yes | No (each block depends on prior) |
| Padding required | No (stream cipher mode) | Yes (PKCS#7) |
| Padding oracle attacks | Immune | Vulnerable |
| Nonce sensitivity | Critical (never reuse) | IV reuse weakens but doesn’t break |
| NIST recommended | Yes | Superseded for most uses |
The verdict: for new implementations, always prefer AES-256-GCM. The only reason to use CBC today is legacy interoperability.
The Nonce — The Critical Detail
The cryptographic nonce (Number Used Once) is the single most common source of AES-GCM vulnerabilities.
The rule is absolute: never encrypt two different messages with the same key and the same nonce. Doing so allows an attacker to:
- XOR the two ciphertexts together, cancelling out the keystream
- Recover the XOR of the two plaintexts
- Reconstruct both plaintexts if one is known
- Forge valid authentication tags
This attack requires only passive observation — no active interference with your system.
The safe practice is to generate a fresh cryptographically random nonce for every encryption — never a counter starting at zero, never a fixed value, never the same nonce twice with the same key. With 12 random bytes (96 bits), the probability of a collision after one billion encryptions is approximately 1 in 4 billion. For systems that encrypt at extremely high volume, a counter-based nonce scheme synchronized to the key rotation cycle is the professional solution.
Real-World Use Cases
Encrypted file storage
Tools like our file encryptor derive a key from your password using Argon2id, then encrypt
the file with AES-256-GCM using a random nonce stored in the file header. If the file is
modified after encryption — even a single byte — decryption fails and you’re alerted
immediately. This is the correct behavior.
TLS 1.3
AES-256-GCM is one of only two cipher suites permitted in TLS 1.3 (the other is
ChaCha20-Poly1305). Every HTTPS connection you make today likely uses it. The “lock icon”
in your browser means AES-GCM is protecting the connection.
End-to-end encrypted messaging
Signal uses a variant of AES-GCM for message encryption after key exchange.
WhatsApp’s E2E encryption uses the same Signal Protocol. The authentication tag is what
ensures a message from “Alice” can only have been sent by someone with Alice’s key —
not a man-in-the-middle.
Common Mistakes to Avoid
-
Never decrypt before verifying the tag: Some low-level APIs let you decrypt first and check the tag separately. Don’t. Return an error before releasing any plaintext. Timing attacks can extract information from partial outputs.
-
Don’t truncate the authentication tag: 128-bit (16 bytes) is the standard. Shorter tags (32 or 64 bits) are sometimes used for bandwidth, but reduce the security margin significantly. For file encryption, use the full 128 bits.
-
Don’t hardcode nonces: A nonce of all zeros or a sequential counter starting at zero is a common mistake in early implementations. Use
crypto.getRandomValues()or a proven library. -
Don’t use the same key for too many messages: AES-GCM safety bounds suggest rekeying after 2^32 encryptions with the same key. For file encryption, a new key per file (derived from the password + unique salt) sidesteps this issue entirely.
Getting Started
When choosing a tool or evaluating a service, look for explicit AES-256-GCM support in the documentation. Any serious encryption library — in any language — will list it by name. If the documentation only says “AES” without specifying the mode, treat it as a red flag and dig deeper before trusting your data to it.
When assessing a tool’s implementation, three things matter most. First, confirm it generates a unique random nonce for every encryption — not a counter starting at zero, not a fixed value. Second, verify that decryption fails loudly when the authentication tag doesn’t match, rather than silently returning corrupted data. Third, check that the full 128-bit tag length is used, not a truncated version.
For file encryption specifically, prefer tools where AES-256-GCM is paired with a proper key derivation function — ideally Argon2id — so your password is never used as the key directly. Tools that use AES-256-GCM alone without a KDF are vulnerable to weak passwords in a way that the algorithm itself cannot compensate for. See our companion article on Argon2id vs PBKDF2 for the full picture on how passwords become encryption keys safely.
For the other mandatory cipher suite in TLS 1.3, read our guide on ChaCha20-Poly1305.
FAQ
Common questions — answered in plain English.
What does AES-256-GCM stand for?
Is AES-256-GCM the same as AES-256?
What happens if the GCM authentication tag verification fails?
Why is the nonce important in AES-GCM?
Should I use AES-256-GCM or ChaCha20-Poly1305?
Is AES-256-GCM quantum-safe?
References
- [1]NIST SP 800-38D: GCM Mode RecommendationNIST, 2007
- [2]Web Crypto API — SubtleCrypto.encrypt()MDN Web Docs, 2024
- [3]Nonce-Disrespecting Adversaries: Practical Forgery AttacksIACR ePrint, 2016
- [4]OWASP Cryptographic Storage Cheat SheetOWASP, 2024
- [5]Cryptographic Right Answers — LatacoraLatacora, 2018