A field guide · 2012 → today

WebCrypto has quietly been here for over a decade.

It's the browser's built-in cryptographic primitive library — native, hardware-accelerated, and sitting one crypto.subtle call away in every modern browser.

01 What it actually is

The browser already speaks AES.

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.

02 How we got here

A slow, boring rollout — which is exactly what you want from crypto.

2007
NIST publishes SP 800-38D
The foundational spec for Galois/Counter Mode. AES-GCM exists on paper long before browsers touch it.
2012
W3C Web Cryptography Working Group forms
Kicked off in May 2012 after a series of W3C security workshops. The group's charter: deliver a JavaScript API for cryptographic primitives.
2013
First Working Draft published
The 25 June 2013 draft lays out the SubtleCrypto shape — encrypt, decrypt, sign, verify, hash, generateKey — that you still use today.
2014–16
Browsers ship it (behind flags, then not)
Chrome, Firefox, and Safari roll out crypto.subtle implementations during Candidate Recommendation. By 2015, AES-GCM works in stable builds of every major engine.
2017
RecommendationW3C finalises the spec
On 26 January 2017, the Web Cryptography API becomes an official W3C Recommendation. That's the moment it stops being "emerging" and starts being "expected."
2017+
Quiet ubiquity
Cloudflare Workers, Deno, and Node.js (18+) all implement the same crypto.subtle interface. The browser API becomes the edge API becomes the server API.
2025
Level 2Working on the next revision
Web Cryptography Level 2 is in active development — adding new algorithms (Ed25519, X25519, SHA-3) while keeping the existing surface stable.
03 Why it's worth knowing

Three reasons it beats shipping a crypto library.

01 / NATIVE
No bundle cost
Zero bytes to ship. Your users already have the implementation installed with their browser. Modern engines wire it straight through to OpenSSL / BoringSSL / platform crypto.
02 / FAST
Hardware-accelerated
On any x86-64 or ARM chip from the last decade, AES-GCM runs on dedicated silicon (AES-NI, ARMv8 crypto extensions). Orders of magnitude faster than JS implementations.
03 / SAFE
Authenticated by default
GCM detects tampering. If someone flips a bit in your ciphertext, decryption throws — you can't accidentally ship a downgrade-attack-prone implementation.
04 Try it now

Encryption, live, in this page.

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.

crypto.subtle · AES-GCM · 256-bit
05 The actual code

It's startlingly short.

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.

A field guide · WebCrypto / AES-GCM
MDN · Spec · WebKit demo