Lion Cipher Lab

Build an HOTP and TOTP Validator From Scratch (and Break the Naive Ones)

Why it matters

Every 2FA tutorial on the internet hands you a library and a QR code, so 'the code changes every 30 seconds' becomes the entire mental model — and that model is wrong in ways that cause real account takeovers. The bugs are never in the HMAC. They are in the verifier: no replay cache, so a code phished thirty seconds ago still works; no throttle, so a script can simply grind the 6-digit space; a drift window widened to shut up support tickets, which multiplies the number of live codes; a plain `==` where a constant-time compare belongs. Writing HOTP and TOTP yourself in fifty lines of…

What you'll learn

Steps in this lab

  1. What a one-time password actually is, and why we build the SERVER half
  2. Set up: a folder, Python, and nothing else
  3. Write the core: HOTP, dynamic truncation, and TOTP
  4. Watch dynamic truncation happen, byte by byte
  5. Prove it: run the official RFC 4226 and RFC 6238 test vectors
  6. Write the server: enrolment, the otpauth:// URI, and a verifier you can cripple
  7. Bug 1 — no replay cache: the same live code works over and over
  8. Bug 2 — no throttle: do the arithmetic, then watch it happen
  9. Bug 3 — an over-generous drift window multiplies the live code space
  10. Bug 4 — comparing with == instead of hmac.compare_digest, and how much it really matters
  11. The judgment: when TOTP is right, when it is not, and what to ship

Open the full interactive lab →