What is TOTP?

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 Core Idea

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.

How the Algorithm Works

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:

Step 1 — Derive a time counter (T): T = floor( current_unix_timestamp / 30 ) // A new value every 30 seconds Step 2 — Compute an HMAC-SHA1 hash: hmac = HMAC-SHA1( key=shared_secret, message=int_to_8_bytes(T) ) // 20-byte hash output Step 3 — Dynamic truncation: offset = hmac[19] & 0x0F code = ( hmac[offset] & 0x7F ) << 24 | hmac[offset+1] << 16 | hmac[offset+2] << 8 | hmac[offset+3] Step 4 — Extract 6 digits: totp = code % 1_000_000 → zero-pad to 6 digits
💡 The key point: both the phone and the server run exactly these steps independently. If the shared secret is the same and their clocks agree, they will produce the same 6-digit output — always.

The 30-Second Window

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.

482610T−2
731905T−1
294817NOW ← valid
563042T+1
018374T+2

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.

The Enrolment Flow

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:

1

Server generates a random Base32 secret and stores it (encrypted) against the user's account

2

Server encodes the secret in a QR code and displays it to the user

3

User scans the QR code with their authenticator app — the secret is now stored on the device

4

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.

The QR Code Format

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:

Security Properties

PropertyTOTPWhy 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

TOTP vs SMS One-Time Codes

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.

TOTP vs Hardware Keys (FIDO2/WebAuthn)

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.

Implementing TOTP Without a Library

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.