Only Once Share
encryptionAES-256developers

AES-256-GCM Encryption Explained for Developers

AES-256-GCM is widely considered the gold standard for symmetric encryption. It's used by governments, banks, VPNs, messaging apps, and security tools worldwide. If you're building anything that handles sensitive data, understanding AES-256-GCM is essential. Here's a developer-friendly breakdown.

What the Name Means

  • AES β€” Advanced Encryption Standard, the encryption algorithm itself
  • 256 β€” The key size in bits (256 bits = 32 bytes), the strongest standard variant
  • GCM β€” Galois/Counter Mode, the mode of operation that provides both encryption and authentication

How AES Works (Simplified)

AES is a symmetric block cipher β€” it uses the same key to encrypt and decrypt. It operates on fixed 128-bit (16-byte) blocks of data through multiple rounds of substitution, permutation, and mixing operations:

  1. SubBytes β€” Each byte is substituted using a lookup table (S-box)
  2. ShiftRows β€” Rows of the state matrix are shifted cyclically
  3. MixColumns β€” Columns are mixed using matrix multiplication in a finite field
  4. AddRoundKey β€” The round key (derived from the main key) is XORed with the state

For AES-256, these operations repeat for 14 rounds. The large number of rounds and 256-bit key make brute-force attacks computationally impossible β€” there are 2^256 possible keys, a number larger than the atoms in the observable universe.

Why GCM Mode Matters

AES alone is just a block cipher. You need a "mode of operation" to encrypt data larger than one 16-byte block. GCM (Galois/Counter Mode) is the preferred choice because it provides two things simultaneously:

  1. Confidentiality β€” Data is encrypted and unreadable without the key
  2. Authenticity β€” A cryptographic tag verifies the data hasn't been tampered with

This combination is called AEAD (Authenticated Encryption with Associated Data). The "Associated Data" part is crucial: you can bind additional unencrypted data (like a message ID) to the ciphertext. If the associated data is modified, decryption fails.

The Initialization Vector (IV)

GCM requires a unique Initialization Vector (IV, also called a nonce) for each encryption operation with the same key. The standard recommends a 96-bit (12-byte) random IV. Reusing an IV with the same key is catastrophic β€” it can completely break the encryption and authentication.

For random IVs, the birthday paradox means collision risk becomes significant after about 2^48 (280 trillion) encryptions with the same key. For most applications, this is not a practical concern. If it is, use a key derivation function to generate unique per-message keys.

Implementation with the Web Crypto API

Modern browsers provide the Web Crypto API, which offers hardware-accelerated AES-256-GCM without any external libraries. Here's the core pattern:

// Generate a random key
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true,
  ["encrypt", "decrypt"]
);

// Encrypt
const iv = crypto.getRandomValues(new Uint8Array(12));
const ciphertext = await crypto.subtle.encrypt(
  { name: "AES-GCM", iv, additionalData },
  key,
  plaintextBytes
);

// Decrypt
const plaintext = await crypto.subtle.decrypt(
  { name: "AES-GCM", iv, additionalData },
  key,
  ciphertext
);

Key Derivation with HKDF

In many applications, you don't use the raw key directly. Instead, you derive per-message keys using HKDF (HMAC-based Key Derivation Function):

const derivedKey = await crypto.subtle.deriveKey(
  { name: "HKDF", hash: "SHA-256", salt, info: contextData },
  masterKey,
  { name: "AES-GCM", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

This is the approach used by Only Once Share: a master key is generated per secret, and HKDF-SHA-256 derives the actual encryption key using the secret ID as context. This means each secret has a cryptographically independent key.

Common Pitfalls

  • IV reuse β€” Never reuse an IV with the same key. Generate a fresh random IV for each encryption
  • Key in URL path β€” Never put keys in the URL path (visible in server logs). Use the URL fragment (#) which is client-only
  • Missing authentication β€” Don't use AES-CTR or AES-CBC without separate authentication. Always use GCM or another AEAD mode
  • Custom crypto β€” Don't implement AES yourself. Use the Web Crypto API or established libraries like libsodium
  • Weak key generation β€” Always use crypto.getRandomValues() or crypto.subtle.generateKey(), never Math.random()

Why AES-256 Over AES-128?

AES-128 is considered secure for current threats and is faster. However, AES-256 provides a much larger security margin against future advances, including potential quantum computing attacks. Grover's algorithm could theoretically reduce AES-128's effective security to 64 bits; AES-256 would still offer 128-bit quantum security, which remains strong.

Conclusion

AES-256-GCM is the industry standard for a reason: it provides strong authenticated encryption with excellent performance, especially with hardware acceleration available in modern CPUs and the Web Crypto API. When building security tools, use it correctly β€” random IVs, proper key management, AEAD mode β€” and leverage platform APIs instead of implementing crypto from scratch.

Share secrets securely β€” for free

Only Once Share uses AES-256-GCM encryption with zero-knowledge architecture. No account required.

Try Only Once Share
All posts