Skip to main content

Try it Live

Run AES-GCM examples in the interactive playground

Overview

AES-GCM is an authenticated encryption algorithm combining AES (Advanced Encryption Standard) in Galois/Counter Mode, providing both confidentiality and authenticity with a single key. Ethereum context: Not on Ethereum - Used for encrypted wallet storage (e.g., UTC/JSON keystore format) and secure messaging. Not part of Ethereum protocol. Key features:
  • Authenticated encryption: Confidentiality + integrity in one operation
  • Performance: Hardware-accelerated on modern CPUs
  • Parallelizable: Can encrypt/decrypt blocks in parallel
  • Additional data: Authenticate without encrypting (AAD)
  • Standards-compliant: NIST approved, widely used
  • Key sizes: 128, 192, or 256 bits
  • Implementations: Native Zig (16KB), NO WASM (not in browser crypto standard libs)

Quick Start

API Reference

Key Management

generateKey(bits: 128 | 256): Promise<CryptoKey>

Generates a cryptographically secure AES key. Parameters:
  • bits - Key size (128 or 256 bits)
    • 128-bit: Faster, still very secure
    • 256-bit: Maximum security, recommended for sensitive data

deriveKey(password: string | Uint8Array, salt: Uint8Array, iterations: number, bits: 128 | 256): Promise<CryptoKey>

Derives key from password using PBKDF2-HMAC-SHA256. Parameters:
  • password - User password (string or bytes)
  • salt - Salt for key derivation (≥16 bytes recommended)
  • iterations - PBKDF2 iterations (≥100,000 recommended)
  • bits - Key size (128 or 256)

importKey(keyData: Uint8Array): Promise<CryptoKey>

Imports raw key bytes as CryptoKey.

exportKey(key: CryptoKey): Promise<Uint8Array>

Exports CryptoKey to raw bytes.

Encryption/Decryption

encrypt(plaintext: Uint8Array, key: CryptoKey, nonce: Uint8Array, additionalData?: Uint8Array): Promise<Uint8Array>

Encrypts data with AES-GCM, returns ciphertext with authentication tag appended. Parameters:
  • plaintext - Data to encrypt
  • key - AES key (from generateKey or deriveKey)
  • nonce - 12-byte nonce/IV (must be unique per encryption)
  • additionalData - Optional AAD (authenticated but not encrypted)
Output format:

decrypt(ciphertext: Uint8Array, key: CryptoKey, nonce: Uint8Array, additionalData?: Uint8Array): Promise<Uint8Array>

Decrypts AES-GCM ciphertext, verifies authentication tag. Parameters:
  • ciphertext - Encrypted data with tag
  • key - Same key used for encryption
  • nonce - Same nonce used for encryption
  • additionalData - Same AAD used for encryption (if any)
Throws:
  • InvalidNonceError - Nonce not 12 bytes
  • DecryptionError - Authentication tag verification fails (data tampered), wrong key/nonce/AAD used, or corrupted ciphertext

Nonce Generation

generateNonce(): Uint8Array

Generates cryptographically secure 12-byte nonce.

Constants

Nonce Management

Critical: Never reuse a nonce with the same key!

Safe Nonce Usage

Storage Format

Store nonce with ciphertext (nonce is not secret):

Nonce Collision Risk

With random nonces (12 bytes), collision probability:
  • After 2³² encryptions: ~0.005% chance
  • After 2⁴⁸ encryptions: 50% chance (birthday paradox)
Recommendations:
  • Random nonces: Safe for up to ~2³² encryptions per key
  • Counter-based: Increment counter for each encryption (no collisions)
  • Key rotation: Generate new key periodically to reset nonce space

Additional Authenticated Data (AAD)

AAD is authenticated but not encrypted - useful for metadata:
Use cases:
  • Protocol version numbers
  • Timestamps
  • User IDs
  • Packet headers
  • Database row IDs
Security:
  • AAD is authenticated (tampering detected)
  • AAD is NOT encrypted (readable by anyone)
  • Must provide same AAD for decryption

Password-Based Encryption

Derive key from user password using PBKDF2:

Key Storage

Secure Storage Patterns

1. Environment variables (server-side)
2. Browser (encrypted with password)
3. Hardware Security Modules (HSM)

Security

Critical Warnings

1. Never reuse nonce with same key
2. Use cryptographically secure random
3. Verify authentication tag (automatic)
4. Protect keys at rest
5. Use strong passwords for derivation

Best Practices

1. Key size: Use 256-bit keys for sensitive data
2. PBKDF2 iterations: Balance security vs performance
3. Salt randomness: Use 16+ byte random salt
4. Key rotation: Periodically generate new keys
5. Clear sensitive memory (when possible)

Common Attacks

Nonce Reuse Attack:
  • Same nonce + key reveals XOR of plaintexts
  • Protection: Always generate new nonce
Key Exhaustion:
  • Too many encryptions with same key increases collision risk
  • Protection: Rotate keys periodically
Weak Password:
  • Brute-force PBKDF2-derived keys
  • Protection: Strong passwords + high iteration count
Timing Attacks:
  • Constant-time operations in WebCrypto API
  • Protection: Use native crypto.subtle (not hand-rolled crypto)
Padding Oracle:
  • Not applicable to GCM (no padding)
  • GCM uses stream cipher mode

Performance

Benchmarks (typical)

Encryption speed (AES-256-GCM):
  • Modern CPU with AES-NI: 1-5 GB/s
  • Without hardware acceleration: 50-200 MB/s
Key derivation (PBKDF2):
  • 100,000 iterations: ~50-100ms
  • 600,000 iterations: ~300-600ms

Optimization Tips

1. Batch operations when possible
2. Reuse keys (but rotate periodically)
3. Adjust PBKDF2 iterations for use case

Use Cases

File Encryption

Database Field Encryption

Secure Messaging

Error Handling

All AesGcm functions throw typed errors that extend CryptoError:
All error classes have:
  • name - Error class name (e.g., "DecryptionError")
  • code - Machine-readable error code
  • message - Human-readable description
  • docsPath - Link to relevant documentation

Implementation Notes

  • Uses native WebCrypto API (crypto.subtle)
  • Hardware-accelerated on modern CPUs (AES-NI)
  • Constant-time operations (timing attack resistant)
  • NIST SP 800-38D compliant
  • 128-bit authentication tag (maximum security)
  • 96-bit nonce (12 bytes, standard for GCM)

References