TOTP Demo
An interactive playground for time-based one-time passwords. Generate a secret, scan the QR with your own authenticator app, watch the six digits roll over every thirty seconds, and verify what your phone produces. Every code is computed in the browser with the Web Crypto API — the page makes no network calls at all.
An interactive playground for the algorithm behind every authenticator app. Enroll a secret, scan it with Google Authenticator or Aegis or 1Password, and watch your phone and this page agree on the same six digits without ever talking to each other.
It is the companion piece to TOTP: Why the Authenticator Code Is Right Even When Your Phone Is Offline.
The page walks through the three stages of RFC 6238 in order:
- Register. Generates a random Base32 secret and renders it as an
otpauth://QR code, exactly as a real service would at enrollment. Issuer, account, digit count, period, and hash algorithm are all editable, so you can see what each knob changes. - Current code. Shows the live code with a countdown to the next rollover, and the previous and next codes either side of it — which is what a server’s ±1 acceptance window is actually tolerating.
- Verify. Type in whatever your authenticator app is showing and the page checks it the way a server would, window included.
The interesting part is what the page does not do. There is no backend. Codes are derived locally with crypto.subtle — importKey for the shared secret, then HMAC over the current time step — and no request ever leaves the browser. That is the whole point of TOTP, made literal: open devtools, watch the network tab stay empty, and the codes keep matching your phone.
- Live QR code for enrollment in any standard authenticator app
- Configurable digits, period, and hash algorithm
- Previous / current / next codes shown together, to make the drift window visible
- Verification with the same ±1 step window a real server uses
- Computed entirely client-side with the Web Crypto API — no backend, no requests
- Vanilla JavaScript, no framework