demo · v140

Credential Roundtrip

A classic WebAuthn / WebCrypto flow: generate random bytes for a challenge, ship them to a server as base64url, get them back and verify. Pre-140 every browser had to glue together btoa + String.fromCharCode + a hand-rolled base64url tweak. Chrome 140 ships native Uint8Array.toBase64(). Side-by-side timings.

1 · raw challenge (Uint8Array)

click "Generate" to start

2 · base64url (native)

3 · hex (native)

4 · roundtrip — fromBase64 → bytes → equals original

legacy (btoa + String.fromCharCode)
— ms
native (toBase64)
— ms
// Chrome 140+
const challenge = crypto.getRandomValues(new Uint8Array(32));
const b64u = challenge.toBase64({ alphabet: "base64url" });
const hex  = challenge.toHex();
const back = Uint8Array.fromBase64(b64u, { alphabet: "base64url" });

// pre-140 — the gnarly version
const b64u_old = btoa(String.fromCharCode(...challenge))
  .replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");

see also