How does a TOTP authenticator app generate those 6-digit codes?
Short answer
TOTP (Time-based One-Time Password) combines a shared secret, established at enrollment, with the current time divided into fixed windows (usually 30 seconds). It runs HMAC over the time-step counter with the secret, then truncates the result to a 6-digit code. Both the app and server hold the same secret and clock, so they independently compute the same code — no network call needed. The code rotates each window.
This question checks whether you understand that authenticator codes are computed, not delivered — there's no message in transit to intercept, which is what makes TOTP stronger than SMS.
The setup
When you enroll, the server generates a random shared secret and shows it to your app, usually as a QR code (the otpauth:// URI). Both the server and your authenticator app now hold the same secret. Nothing about that secret travels over the network again.
Generating a code
TOTP is built directly on HMAC (it's HOTP with a time-based counter). The current Unix time is divided by a step size — typically 30 seconds — to produce a counter value. The app computes HMAC(secret, time_step), then applies a defined dynamic truncation to squeeze that digest down to a 6-digit number. Because the input is the time window, the code changes every 30 seconds. The server, holding the same secret and reading the same clock, computes the identical code and compares. No round trip, no SMS, no email — which removes the SIM-swap and interception risks that plague SMS OTP.
Handling clock drift
Phones and servers don't have perfectly synced clocks, so servers typically accept the code from the adjacent time windows (one step before/after) to tolerate small drift, balancing usability against the slightly larger guessing window.
The limitation
TOTP is not phishing-resistant. A real-time phishing proxy can present a fake login page, capture both the password and the live 6-digit code, and replay them to the real site within the 30-second window. That's why FIDO2/passkeys — which cryptographically bind the credential to the legitimate origin — are the gold standard. TOTP is still far better than SMS and a solid second factor for most apps.
What interviewers look for
The shared-secret-plus-time HMAC computation, "computed offline, not transmitted," the 30-second rotation and clock-drift tolerance, and honesty that TOTP can still be real-time phished while SMS is weaker still.
Likely follow-ups
- Why can TOTP still be phished in real time, and what fixes that?
- How do servers handle clock drift between the app and the server?
- Why must the shared secret be protected at rest on both ends?