A deep dive into Time-based One-Time Passwords — the algorithm behind Google Authenticator
TOTP stands for Time-based One-Time Password. It is an open standard — defined in RFC 6238 — that generates short-lived numeric codes from a shared secret and the current time. It is the technology underpinning Google Authenticator, Authy, Microsoft Authenticator, 1Password, and virtually every other authenticator app in widespread use today.
The fundamental insight of TOTP is elegant: if two parties share a secret and both have access to an accurate clock, they can independently compute the same value at the same moment in time — without any communication. This makes the code impossible to predict in advance and useless after its window expires.
In practice, a user's phone and your server both know the same shared secret (established during setup by scanning a QR code). At login time, the phone and server both independently compute a 6-digit code from that secret and the current Unix timestamp. If the codes match, authentication succeeds — no network communication about the code itself is required, and an intercepted code is worthless within seconds.
The TOTP algorithm is built on top of HOTP (HMAC-based One-Time Password, RFC 4226), replacing a counter value with a time-derived counter. The steps are:
By dividing the Unix timestamp by 30, TOTP creates a rolling "window" — a slot of time during which a particular code is valid. Each window boundary generates a completely different code.
To tolerate minor clock drift between devices, implementations typically accept the code from one window either side of the current one — meaning a code is effectively valid for up to 90 seconds in practice. This behaviour is specified in RFC 6238 and is configurable.
Before TOTP can be used for authentication, the server and the user's device must share a secret. This happens during a one-time enrolment step:
Server generates a random Base32 secret and stores it (encrypted) against the user's account
Server encodes the secret in a QR code and displays it to the user
User scans the QR code with their authenticator app — the secret is now stored on the device
User enters the first code to confirm successful enrolment
From this point on, the secret lives in two places only: your encrypted database and the user's phone. It is never transmitted again during authentication — only the derived code is sent.
Authenticator apps read secrets via a standardised URI format called otpauth://. The QR code displayed during enrolment encodes a URI like this:
otpauth://totp/MyApp:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp
The components are:
| Property | TOTP | Why it matters |
|---|---|---|
| Short-lived codes | ✓ Strong | Each code expires in 30 seconds, rendering phished codes worthless almost immediately |
| Replay resistance | ✓ Strong | A code intercepted in transit cannot be reused after its window expires |
| Secret never transmitted at login | ✓ Strong | Only the derived code travels over the network — the underlying secret stays on device and server |
| Works offline | ✓ Strong | The device generates codes without any network connectivity |
| Open standard | ✓ Strong | RFC 6238 is publicly audited; no proprietary black boxes |
| Phishing resistance | ⚠ Moderate | Better than SMS but not as strong as hardware keys (FIDO2/WebAuthn) — a real-time phishing proxy can relay a valid code within its window |
| Device loss | ⚠ Plan required | If the user loses their phone, recovery codes or an admin reset process are needed |
SMS-based one-time codes work on a similar principle but are fundamentally less secure because:
For all these reasons, security guidelines from NIST, the UK NCSC, and major cloud providers now recommend app-based TOTP over SMS wherever possible.
Hardware security keys such as YubiKeys use the FIDO2/WebAuthn standard and provide stronger phishing resistance than TOTP, because the cryptographic challenge is bound to the specific origin (domain) of the site being logged into. A phishing site on a different domain cannot extract a valid credential even if the user is fooled into entering their password there.
However, TOTP remains the most practical second factor for most applications: it requires no hardware purchase, works across all devices, and is universally supported by end users who already have a smartphone.
Because TOTP is built on standard cryptographic primitives (HMAC-SHA1) and simple integer arithmetic, it is straightforward to implement natively in any programming language. You don't need a dedicated TOTP library — you just need:
Alternatively, AuthenticatorAPI.com handles all of this for you — just call the Validate endpoint with the PIN and your secret, and receive a simple true or false response.