ToolMight LogoToolMight
August 2, 2026
2 min read
By ToolMight Team

In-Browser Cryptography: Implementing AES-GCM Encryption with Web Crypto API

Learn how to use native W3C Web Cryptography APIs (crypto.subtle) in JavaScript to encrypt sensitive data client-side with AES-256-GCM, PBKDF2 key derivation, and RSA-OAEP.

#security#cryptography#javascript#web-crypto

Handling sensitive developer data requires a zero-trust security posture. Relying on server-side HTTP endpoints for symmetric encryption or key generation exposes user payloads to network interception and server logging risks.

Fortunately, modern web browsers feature the native W3C Web Cryptography API (window.crypto.subtle), providing hardware-accelerated cryptographic primitives directly in client JavaScript.

In this guide, we will implement client-side AES-256-GCM encryption, PBKDF2 key derivation, and secure initialization vector (IV) handling.


1. Why Use Native crypto.subtle Over Third-Party NPM Packages?

Legacy JavaScript applications frequently relied on third-party libraries (like crypto-js) for encryption. Native browser cryptography offers distinct advantages:

  1. Hardware Acceleration: Operations execute directly in native C++ browser code utilizing CPU instruction sets (AES-NI).
  2. Secure Key Isolation: Cryptographic keys can be marked as non-extractable (extractable: false), preventing malicious XSS scripts from reading raw key bytes out of memory.
  3. Zero Dependencies: Eliminates supply-chain supply attack risks associated with unverified NPM crypto packages.

2. Deriving an AES-256 Key from a Password (PBKDF2)

Never use a raw string password directly as an encryption key. Always pass the password through a key derivation function with a cryptographic salt:

async function deriveKey(password, salt) {
  const enc = new TextEncoder();
  
  // 1. Import raw password string into a KeyMaterial object
  const passwordKey = await crypto.subtle.importKey(
    "raw",
    enc.encode(password),
    "PBKDF2",
    false,
    ["deriveKey"]
  );

  // 2. Derive a 256-bit AES-GCM Key using 100,000 PBKDF2 iterations
  return await crypto.subtle.deriveKey(
    {
      name: "PBKDF2",
      salt: salt,
      iterations: 100000,
      hash: "SHA-256"
    },
    passwordKey,
    { name: "AES-GCM", length: 256 },
    false, // Non-extractable key
    ["encrypt", "decrypt"]
  );
}

3. Encrypting Payloads with AES-GCM

AES-GCM requires a unique 96-bit Initialization Vector (IV) for every encryption operation:

async function encryptData(plaintext, password) {
  const enc = new TextEncoder();
  const salt = crypto.getRandomValues(new Uint8Array(16));
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 96-bit IV
  
  const key = await deriveKey(password, salt);

  const ciphertext = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv: iv },
    key,
    enc.encode(plaintext)
  );

  return { ciphertext, salt, iv };
}

4. Test In-Browser Encryption Utilities

Want to generate RSA-2048/4096 key pairs or encrypt/decrypt payloads with AES-256-GCM locally? Try our browser-native AES Cipher, RSA Key Generator, and Hash Generator tools on ToolMight. All cryptographic operations run 100% locally using window.crypto.subtle.

TM

Written by ToolMight Editorial

Verified Team

ToolMight is a comprehensive suite of browser-only utilities crafted by an experienced team of software developers and web specialists. While we thoroughly test every utility and guide for reliability and accuracy, all outputs are provided for educational and diagnostic purposes, and should be validated in accordance with our Terms of Service.

Frequently Asked Questions

Q: What is the W3C Web Cryptography API?

The Web Cryptography API (`window.crypto.subtle`) is a native W3C browser interface for performing low-level cryptographic operations (encryption, decryption, hashing, signature verification, and key derivation) using hardware acceleration.

Q: Why is AES-GCM preferred over AES-CBC?

AES-GCM (Galois/Counter Mode) provides authenticated encryption with associated data (AEAD). Unlike AES-CBC, GCM verifies data integrity and authenticity simultaneously, preventing padding oracle attacks.

Q: How do I derive a cryptographic key from a user password?

Use `crypto.subtle.deriveKey()` with PBKDF2 (Password-Based Key Derivation Function 2), specifying a high iteration count (e.g., 100,000+ iterations) and a secure random salt.

You might also like