Guides Security

How Two-Factor Codes (TOTP) Work

How the six-digit codes in an authenticator app are derived from a shared secret and the clock, with a verified RFC test vector, plus their limits against phishing.

Last reviewed:

AdSense Placeholder
Slot: header_reference_page
On this page

A time-based one-time password (TOTP) is a short code that changes every 30 seconds. Your authenticator app and the website both know a shared secret and the current time, so each can compute the same code on its own. The method is defined in RFC 6238, which builds on the counter-based HOTP in RFC 4226. Try it with the TOTP Generator.

The algorithm in five steps

  1. Turn time into a counter. counter = floor(unix_time / 30).
  2. HMAC the counter. Compute HMAC-SHA1 (or SHA-256/512) of the 8-byte big-endian counter, keyed with the secret. You can experiment with the HMAC Generator.
  3. Pick four bytes. The last nibble of the result is an offset; take the four bytes starting there.
  4. Clear the top bit. Mask with 0x7FFFFFFF so the number is positive.
  5. Keep the last digits. Take the number modulo 10⁶ (for six digits), padded with zeros.

A verified example

The RFC 4226 test secret is the ASCII string 12345678901234567890, which in the Base32 form used by authenticator apps is GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ. For counters 0, 1 and 2, HOTP gives 755224, 287082 and 359152.

For TOTP, RFC 6238 uses time 59 seconds with a 30-second step and 8 digits:

Step Value
Counter 59 ÷ 30 → 1
HMAC-SHA1 75a48a19d4cbe100644e8ac1397eea747a2d33ab
Offset (last nibble) 11
Four bytes, top bit cleared 1094287082
Last 8 digits 94287082

The six-digit version of the same code is 287082. Convert timestamps with the Unix Timestamp Converter to see which step a moment falls into.

What is in the QR code

The QR code holds an otpauth://totp/... link carrying the secret, issuer, number of digits, period and algorithm, for example otpauth://totp/Example:[email protected]?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=Example&digits=6&period=30. Anyone who sees the secret can generate your codes, so treat it like a password.

Limits

Method Phishing resistant Notes
SMS codes No Can be intercepted or SIM-swapped
TOTP app No Better than SMS, but a fake site can relay the code
Hardware key or passkey Yes Checks the site's real domain

Common pitfalls

  • Wrong clock. The most common cause of rejected codes.
  • Losing the secret. Keep the backup codes or the original setup key somewhere safe, or you may be locked out.
  • Pasting real secrets into web pages. Use the generator with test secrets only.
  • Reusing a code. Each code is valid for one step; servers usually reject a replay.

See How to Generate Strong Passwords and Passphrases for the first factor, and HMAC and Multi-factor authentication (MFA) for definitions.

Try these tools

See also

  • Glossary TOTP
    TOTP (time-based one-time password) is a short code, usually six digits, derived from a shared secret and the current time.
  • Glossary HOTP
    HOTP (HMAC-based one-time password) is a one-time code derived from a shared secret and a counter that increases each time a code is used.
  • Glossary HMAC
    HMAC (hash-based message authentication code) is a hash computed with a secret key.
  • Glossary Multi-factor authentication (MFA)
    Multi-factor authentication (MFA) requires two or more kinds of proof to sign in.
  • Guide How Hashing Works
    What a hash function does, the avalanche effect shown with real SHA-256 output, which algorithms are still safe, HMAC.

Frequently Asked Questions

The code depends on the clock. If your device's time is off by more than about a step (usually 30 seconds), the server computes a different code. Turn on automatic time on the device.

No. Both hold the same secret and read the same time, so each computes the same code independently. The secret is exchanged once, when you scan the QR code.

Yes. A fake login page can ask for the code and use it immediately, because the code is valid for any site that asks. Hardware security keys and passkeys check the real site's address, which is why they resist phishing.

AdSense Placeholder
Slot: footer_leaderboard