Online Dev Tools

Developer & Security Tools for IT Professionals

Fuel The Infrastructure
Blog

TOTP and 2FA Explained: How the 6-Digit Code Actually Works


Everyone uses the six-digit codes from an authenticator app, but few people know what generates them. It is worth understanding, because once you do, the mysterious failures — "invalid code," codes that stop working, codes that differ between devices — all have obvious explanations. The mechanism is TOTP, and it is simpler than it looks.

The core idea: HMAC over time

TOTP (Time-based One-Time Password, RFC 6238) combines two ingredients:

  1. A shared secret — a random key created once, when you set up 2FA, and stored by both the server and your authenticator app.
  2. The current time, divided into fixed windows (usually 30 seconds).

To produce a code, both sides compute HMAC(secret, current_time_window), then run a standard "dynamic truncation" step that squeezes the HMAC down to 6 digits. Because both sides share the same secret and read the same clock, they independently arrive at the same 6 digits — without ever exchanging the code. Every 30 seconds the time window advances, so the code rotates. That is the whole scheme. You can watch it happen in the TOTP / 2FA Code Generator: give it a Base32 secret and it shows the current code and the countdown, computed entirely in your browser.

The signing operation is the same HMAC primitive used all over cryptography — the kind the Hash Generator demonstrates — applied to a counter derived from the clock.

What the QR code actually contains

When you scan a 2FA setup QR code, you are not scanning the codes — you are scanning the secret (plus metadata like the account name, issuer, digit count, and period), encoded in an otpauth:// URL. From that moment, your app can generate every future code on its own, offline. That is why authenticator apps work with no signal: nothing is fetched per code; it is all local math over the clock.

This also explains why the setup secret is so sensitive: anyone who has it can generate valid codes forever. Treat it like a password. If you need to move a secret between systems while testing, share it through Secure Paste rather than pasting it into chat, and generate throwaway test secrets rather than reusing real ones.

Why codes fail

Almost every "invalid code" comes down to one of three things:

TOTP vs SMS

TOTP is meaningfully stronger than SMS codes because nothing is transmitted per login: there is no text message to intercept and no phone number to hijack via SIM swap. The trade-off is recoverability — lose the secret (and your backup codes) and you are locked out — which is why saving backup codes at setup matters.

The takeaway

A 2FA code is just HMAC(shared secret, current 30-second window) truncated to six digits, computed independently on both ends. Knowing that, the failures demystify themselves: skewed clocks, mismatched digits/period/algorithm, or a botched secret. When you need to verify a setup or reproduce a code by hand, the TOTP / 2FA Code Generator does exactly what your authenticator app does — just where you can see the moving parts.

Sources

  1. RFC 6238 (TOTP) — https://www.rfc-editor.org/rfc/rfc6238
  2. RFC 4226 (HOTP) — https://www.rfc-editor.org/rfc/rfc4226

Related tools