python 36 lines · 7 steps

How TOTP two-factor codes work

A from-scratch implementation of time-based one-time passwords, from secret generation to time-window verification.

Explained by highlit
1import base64
2import hashlib
3import hmac
4import os
5import struct
6import time
7from urllib.parse import quote
8 
9 
10def generate_secret(length: int = 20) -> str:
11 return base64.b32encode(os.urandom(length)).decode("ascii").rstrip("=")
12 
13 
14def provisioning_uri(secret: str, account: str, issuer: str) -> str:
15 label = quote(f"{issuer}:{account}")
16 params = f"secret={secret}&issuer={quote(issuer)}&algorithm=SHA1&digits=6&period=30"
17 return f"otpauth://totp/{label}?{params}"
18 
19 
20def totp(secret: str, digits: int = 6, period: int = 30, at: float | None = None) -> str:
21 padding = "=" * (-len(secret) % 8)
22 key = base64.b32decode(secret.upper() + padding)
23 counter = int((at or time.time()) // period)
24 msg = struct.pack(">Q", counter)
25 digest = hmac.new(key, msg, hashlib.sha1).digest()
26 offset = digest[-1] & 0x0F
27 code = struct.unpack(">I", digest[offset:offset + 4])[0] & 0x7FFFFFFF
28 return str(code % (10 ** digits)).zfill(digits)
29 
30 
31def verify(secret: str, code: str, window: int = 1) -> bool:
32 now = time.time()
33 return any(
34 hmac.compare_digest(totp(secret, at=now + drift * 30), code)
35 for drift in range(-window, window + 1)
36 )
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1TOTP is just HMAC over a time counter, truncated down to a short numeric code.
  2. 2Both parties derive the same code from a shared secret without ever exchanging it.
  3. 3A small verification window absorbs clock skew between the client and server.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How TOTP two-factor codes work — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code