Live model · Authenticator codes

How Authenticator Codes Actually Work

An authenticator app holds a secret it got from the QR code you scanned. Every 30 seconds it counts the time steps since 1970, hashes that count with the secret using HMAC-SHA1, and cuts the 20-byte result down to 6 digits. The server holds the same secret and does the same math, so nothing travels to your phone.

One code, byte by byte

The secret is 32 base32 letters, 20 bytes or 160 bits. Scanning the QR code stored it on your phone; the server keeps the same bytes. Nothing else is shared.
StopTOTP
Seconds after noonSecret
Clock12:01:15 UTCCounter·

Secret

GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ

32 base32 letters: 20 bytes, 160 bits

Counter

floor(Unix time ÷ 30)

Code

the last 6 digits

HMAC-SHA1

20 bytes

Watch the Python behind this model run, line by line

How to read the stage

The top row is the secret: 20 bytes, here RFC 6238's own test key. At 12:01:15 UTC the counter is 59,752,802. HMAC-SHA1 turns secret and counter into 20 bytes. The last byte, 0x74, ends in 4, so the code is read from bytes 4 to 7: 335,590,644, whose last six digits, 590644, are the code. At 12:01:30 the counter ticks over and 882102 replaces it.

Why it works offline, and why the clock matters

Your phone and the server never talk. Each one makes the code from the shared secret and its own clock, and only the code you type crosses the network. Typing takes time and clocks drift, so the server also tries the codes for nearby time steps. RFC 6238 recommends allowing at most one step for network delay. Below, a phone 40 seconds fast still gets in, on the server's third try.

A phone 40 seconds fast still logs in

At 12:01:15 UTC, your phone and the server each hold the same secret, locked away since you scanned the QR code. They never talk: the phone needs no signal to make a code.
StopChecking a code
Phone clock off by (s)Typing delay (s)Steps either side
True time12:01:15 UTCPhone clock off by+40 sTyping delay5 s

Phone and server

Your phone (offline)
Secret
GEZD…QOJQ
Its clock
12:01:55 UTC (+40 s)
Counter
·
Code on screen
·
Server
Secret
GEZD…QOJQ
Its clock
·
Counter
·
Code typed in
·

The server's window: 1 step either side

StepCounterCoversCodeMatch
-159,752,80112:00:30 to 12:00:59··
now59,752,80212:01:00 to 12:01:29··
+159,752,80312:01:30 to 12:01:59··
  • CH1 the code
  • CH2 clock drift

Watch the Python behind this model run, line by line

What the QR code holds

The QR code is a link that starts otpauth://totp/ and carries a secret parameter: the key in base32, five bits a letter. RFC 4226 asks for a secret of at least 128 bits and recommends 160, the 32 letters on the stage. The format's defaults are SHA-1, 6 digits and 30 seconds, and Google's own description of it says Google Authenticator ignores the setting for any other algorithm or period.

What the model leaves out

The model computes codes and keeps no state. A real server must also refuse a code it has already accepted, which RFC 6238 requires, and limit failed attempts, which RFC 4226 recommends, since a 6-digit code can be guessed one in a million. It may also remember how far your clock drifts. The stage's clock is fixed at noon UTC on 2026-10-21 plus the seconds you set, so every link shows the same codes.

Questions

Does Google Authenticator need an internet connection?
No. Google's help page says you can still generate codes without an internet connection or mobile service. The app needs only the secret it saved when you scanned the QR code and the phone's clock; every code is computed on the phone.
Why do authenticator codes change every 30 seconds?
The code comes from the number of 30-second steps since 1970, so each new step is a new counter and an unrelated code. RFC 6238 recommends 30 seconds as a balance between security and usability; a longer step would leave each code valid for longer.
Why was my 2FA code rejected?
Often the phone's clock is off. Its code then belongs to a time step the server isn't checking, since servers look only a step or two either side of their own time. Try Phone 75 seconds fast under Break it on the second stage. A code typed twice is also refused.
Can someone predict my next code?
Not without the secret. Each code comes from an HMAC of the secret and the counter, and the next counter's HMAC looks nothing like the last: on the stage, 590644 is followed by 882102. Anyone who copies the secret, though, can make every future code, which is why it should never leave the QR code and your app.
Is TOTP the same as HOTP?
TOTP is HOTP with the clock as its counter. HOTP, from RFC 4226, counts button presses or logins instead, so both sides have to stay in step on a count. TOTP replaces the count with the number of 30-second steps since 1970, which both sides can read from a clock.

More of how it works