Skip to content

← All writing

How TOTP and Authenticator Apps Actually Work

· by Andergrove Software

The six-digit code in your authenticator app is never sent to you by the server. Your phone and the server independently compute the same number from two things they both already hold: a shared secret set up once, and the current time. That is why the code works offline, rotates every 30 seconds, and cannot be captured by intercepting a message in transit. This is TOTP, the Time-based One-Time Password.

Here is how it works end to end, and what that means for keeping your accounts safe. TOTP is built on HMAC, so the HMAC explainer is useful background.

The shared secret

Two-factor setup starts by giving your app a secret. When you scan that QR code you are not scanning a code or a link; you are importing an otpauth:// URI that contains:

  • the secret, a random key in Base32,
  • the account and issuer labels (so the app shows "GitHub: you@example.com"),
  • and parameters: the algorithm (usually SHA-1), the number of digits (usually 6), and the period (usually 30 seconds).

That secret is the only sensitive part. The server keeps its copy, your app keeps its copy, and from then on neither has to send it again.

The code is an HMAC of the time

Every 30 seconds, both sides run the same calculation:

  1. Take the current Unix time and divide it by 30 to get a time-step counter, the number of 30-second intervals since 1970 (see Unix timestamps).
  2. Compute HMAC-SHA1(secret, counter). HMAC is a keyed hash, so without the secret you cannot produce the right output (see HMAC vs. hashing).
  3. Truncate that hash down to a 6-digit number using a fixed rule from the spec.

Because both sides share the secret and read the same clock, they independently arrive at the same six digits, with no communication. When the counter ticks into the next 30-second window, the HMAC input changes and so does the code.

Why both sides agree (and clock drift)

The whole scheme relies on the two clocks being roughly in sync. They never match exactly, so:

  • Servers usually accept the code from the current window plus one step on either side, tolerating about 30 seconds of drift in each direction.
  • If your phone's clock is wrong (manual time, or a flat battery resetting it), codes can start failing. The fix is to turn on automatic network time.

That small window is also why the code is "one-time" in practice: it is valid only for its 30-second slot, and a careful server also refuses a code that was already used within its window.

TOTP vs. SMS, push, and passkeys

TOTP is a solid second factor, but it is not the only one:

  • SMS codes are the weakest: they travel over a channel exposed to SIM-swapping and interception. Better than nothing, worse than TOTP.
  • TOTP keeps the secret on your device and needs no signal, but it is phishable: a fake login page can ask for your current code and replay it within 30 seconds.
  • Push approvals are convenient but prone to "MFA fatigue", where an attacker spams prompts hoping you tap approve.
  • Passkeys (WebAuthn) are the strongest mainstream option: they are bound to the real site's domain, so they cannot be phished. Prefer passkeys where they are offered, and use TOTP where they are not.

What an attacker actually needs

The key insight for your own safety: the security lives in the secret, not the rotating code. A stolen six-digit code is useless within 30 seconds, but anyone who gets your TOTP secret can generate valid codes forever. So:

  • Treat the setup secret (and its QR) like a password. Do not paste it into chats or store it in plain text.
  • Keep a backup. Save the secret or the site's recovery codes somewhere safe, or you can be locked out if you lose your phone. Many authenticator apps now offer encrypted cloud backup.
  • Remember TOTP defends against a leaked or guessed password, but not a phishing page that relays your code in real time. That gap is exactly what passkeys close.

See it work

The Andergrove TOTP generator computes codes from a Base32 secret right in your browser, with a live countdown, so you can watch the digits roll over every 30 seconds and confirm that the same secret plus the same time always produces the same code. Pair 2FA with a strong, unique password (see how long it takes to crack a password) and you have a serious barrier on your accounts.