It's the browser's built-in cryptographic primitive library — native, hardware-accelerated, and sitting one crypto.subtle call away in every modern browser.
The Web Cryptography API (exposed as window.crypto.subtle) gives JavaScript access to low-level cryptographic operations — hashing, signing, key generation, and authenticated encryption — without shipping a single byte of crypto library to the client.
AES-GCM is the algorithm most developers reach for. It's AES (the Advanced Encryption Standard) running in Galois/Counter Mode, which means it encrypts and authenticates in one pass — any tampering with the ciphertext produces a decryption failure, not a silent garbage payload. That built-in authentication is why GCM is usually recommended over CBC or CTR modes.
SubtleCrypto shape — encrypt, decrypt, sign, verify, hash, generateKey — that you still use today.crypto.subtle implementations during Candidate Recommendation. By 2015, AES-GCM works in stable builds of every major engine.crypto.subtle interface. The browser API becomes the edge API becomes the server API.This runs entirely in your browser. Type something, generate a 256-bit AES key, encrypt, tamper if you like, then decrypt. Every byte of ciphertext is produced by the same crypto.subtle your backend calls.
The entire demo above, minus the UI wiring, is this:
// generate a 256-bit AES-GCM key const key = await crypto.subtle.generateKey( { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt'] ); // encrypt — IV must be unique per message, 96 bits is the sweet spot const iv = crypto.getRandomValues(new Uint8Array(12)); const ciphertext = await crypto.subtle.encrypt( { name: 'AES-GCM', iv }, key, new TextEncoder().encode('hello') ); // decrypt — throws if the ciphertext or auth tag has been tampered with const plain = await crypto.subtle.decrypt( { name: 'AES-GCM', iv }, key, ciphertext ); console.log(new TextDecoder().decode(plain)); // 'hello'
A few things worth internalising: never reuse an IV with the same key (catastrophic in GCM), use a 96-bit random IV unless you have a reason not to, and remember the auth tag is appended to the ciphertext automatically — you don't manage it separately.