How OTP and Two-Factor Authentication Actually Work
From shared cryptographic secrets and Unix timestamps to dynamic truncation and SMS delivery risks
“How can an authenticator app generate the exact 6-digit code as a server without any internet connection?”
Time-based one-time passwords (TOTP) do not rely on cellular towers, SMS gateways, or an internet connection. Both your phone and the server independently calculate the exact same 6-digit number using a shared secret and the current tick of Unix time.
- How does an authenticator app work without internet?
- What is the math behind TOTP codes?
- Why is SMS OTP less secure than an authenticator app?
- How does clock drift affect one-time passwords?
To build a complete first-principles mental model of this mechanism, we recommend starting with these foundational explainers:
Quick answer
When you log into a secure account, entering a password verifies something you know. But because passwords are frequently leaked in data breaches, re-used across websites, or stolen through phishing, modern security requires Two-Factor Authentication (2FA).
2FA demands a second, independent proof of identity drawn from three classic security factors:
- Something you know: A password, PIN, or security question.
- Something you have: A smartphone, an authenticator app, or a physical hardware security key (like a YubiKey).
- Something you are: A biometric reading, such as Face ID or a fingerprint.
Most people encounter 2FA as a temporary six-digit One-Time Password (OTP). However, there is a fundamental architectural split between the two most common ways these numbers reach your screen:
- SMS OTP: The server generates a random six-digit number, stores it in a temporary database cache for five minutes, and transmits it to your phone over the global telecommunication network via cellular text message.
- Authenticator App (TOTP): No code is ever transmitted over the network. Your phone and the server independently compute the exact same six-digit number at the exact same moment, using a shared cryptographic key and the current tick of Unix time.
Because Time-Based One-Time Passwords (TOTP) rely strictly on local mathematics, your authenticator app functions flawlessly inside an airplane cabin at 35,000 feet with cellular radios and Wi-Fi completely turned off.
The simple mental model: Synchronized Cryptographic Clocks
When you configure Google Authenticator, 1Password, or Apple Keychain by scanning a QR code, you are not establishing a continuous internet connection between your phone and the company's servers.
You are simply transferring a single string of random bytes—called the Shared Secret (K)—into your phone's local storage. From that moment onward, your phone and the server act like two synchronized mechanical clocks ticking forward in 30-second intervals:
Neither device needs to speak to the other until you type the six digits into your browser.
The Mathematical Engine: RFC 6238 (TOTP)
The open standard governing authenticator apps is RFC 6238, known as the Time-Based One-Time Password (TOTP) algorithm. It is built on top of RFC 4226 (HOTP), which originally generated codes based on an incrementing counter.
TOTP transforms an event-based counter into a time-based counter by running four mechanical steps:
┌────────────────────────────────────────────────────────┐
│ The TOTP Algorithm (RFC 6238) │
│ │
│ Unix Epoch Time (e.g. 1773738012 seconds) │
│ │ │
│ ▼ Divide by 30 seconds & floor │
│ Time Counter T = 59,124,600 │
│ │ │
│ ▼ Hash with Shared Secret K │
│ HMAC-SHA-1(K, T) │
│ │ │
│ ▼ 20-byte cryptographic digest │
│ [0x1f, 0xa4, 0x8b, ..., 0x5c, 0x09] │
│ │ │
│ ▼ Dynamic Truncation (4-byte extraction) │
│ 31-bit Unsigned Integer P = 348,912,419 │
│ │ │
│ ▼ Modulo 1,000,000 │
│ 6-Digit TOTP Code: 912419 │
└────────────────────────────────────────────────────────┘
Step 1: The Shared Secret (K)
During initial enrollment, the authentication server generates a cryptographically secure random sequence of bytes (typically 160 bits / 20 bytes).
To make it easy for a camera to ingest, this secret is encoded into a Base32 string (which uses uppercase letters A–Z and digits 2–7 to avoid visual confusion between 0 and O, or 1 and I) and wrapped inside a standard URI:
otpauth://totp/AcmeCloud:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=AcmeCloud
When you point your smartphone camera at the QR code, the authenticator app reads that URI, extracts JBSWY3DPEHPK3PXP, and writes it into the phone's encrypted hardware enclave.
Step 2: The Time Counter (T)
Both your phone and the server check the current Unix epoch time (the total number of seconds elapsed since January 1, 1970, 00:00:00 UTC).
Because human fingers need time to read and type numbers, the algorithm divides the current timestamp into discrete 30-second time steps (X = 30):
Where T0 is the start time (conventionally 0).
If the current time is 1,773,738,012, dividing by 30 and dropping the remainder yields a single integer:
For the next 30 seconds, this counter T remains completely static. At second 31, it increments by exactly 1.
Step 3: The Cryptographic Hash (HMAC)
The algorithm packs the counter T into an 8-byte big-endian binary integer (leveraging the binary operations covered in How Binary and Logic Gates Became Computation) and hashes it together with the secret key K using HMAC (Hash-based Message Authentication Code, RFC 2104):
While RFC 4226 originally specified HMAC-SHA-1 (and most otpauth:// QR codes still default to SHA1 for broad app compatibility), RFC 6238 explicitly supports HMAC-SHA-256 and HMAC-SHA-512 as drop-in replacements. Importantly, even though raw unkeyed SHA-1 is deprecated for digital certificates due to collision attacks, HMAC-SHA-1 remains cryptographically secure for TOTP: HMAC's security proof relies on the keyed pseudorandom function (PRF) property of the nested hash construction H((K ⊕ opad) ∥ H((K ⊕ ipad) ∥ T)), which is unaffected by unkeyed SHA-1 collision attacks.
HMAC guarantees two essential properties:
- Keyed One-Wayness: An attacker who observes thousands of 6-digit outputs cannot invert the HMAC to recover the 160-bit shared secret K.
- Avalanche Effect: A change of even 1 in the time counter T (triggered every 30 seconds by the quartz and atomic clock synchronization described in How Clocks Actually Measure Time) completely and unpredictably scrambles the resulting 20-byte digest.
Step 4: Dynamic Truncation
The resulting hash HS is 20 bytes (160 bits) long (or 32/64 bytes for SHA-256/SHA-512). A human cannot type a 40-character hexadecimal string every 30 seconds. The algorithm must deterministically extract six decimal digits.
To do this cleanly, RFC 4226 specifies Dynamic Truncation:
- Take the final byte of the hash digest (HS[19] for SHA-1).
- Mask its lowest 4 bits (
HS[19] & 0x0F). This produces a dynamic byte offset between0and15. - Read 4 consecutive bytes from the digest starting at that offset:
- Mask off the most significant bit (
& 0x7FFFFFFF) so the 4-byte slice is always interpreted as an unsigned 31-bit integer P ∈ [0, 231−1], avoiding signed/unsigned integer ambiguity across programming languages. - Compute the integer modulo 106:
If P = 348,912,419, then 348,912,419 (mod 1,000,000) = 912419.
If the remainder has fewer than six digits (e.g. 4819), it is zero-padded on the left (004819).
Clock Drift and Window Tolerances
What happens if your phone's clock is 4 seconds fast and the server's clock is 7 seconds slow?
Because time is split into discrete 30-second buckets, a user typing a code at second 29 might see their code rejected if the server has already ticked over to second 31.
To accommodate minor clock drift and network transmission delay, RFC 6238 verifiers check a small sliding tolerance window:
Past Window [T - 1] Current Window [T] Future Window [T + 1]
├───────────────────────┼───────────────────────┼───────────────────────┤
-30s to -1s 0s to +29s +30s to +59s
When you submit a six-digit code, the server computes the expected code for:
- The current interval: T
- The immediately preceding interval: T − 1
- The immediately following interval: T + 1
If your submitted code matches any of those three values, the server accepts the login and can record the observed offset to resynchronize future checks.
Replay Attack Prevention
Accepting a code across a 90-second window introduces a replay risk: an attacker who observes a submitted six-digit code could attempt to submit it again within the same 30-second step.
To prevent this, RFC 6238 mandates that a TOTP code must be single-use. Production authentication servers record the highest accepted time-step counter Tlast per user in an atomic store (such as Redis or the user database row). Once counter T = 59,124,600 is accepted for Alice, any subsequent attempt presenting a code for T ≤ 59,124,600 is rejected immediately.
SMS OTP vs. TOTP vs. Hardware Passkeys: The Complete Security Trade-Offs
While banks and consumer apps widely deploy SMS OTPs because every mobile phone supports text messaging, security standards (including NIST SP 800-63B) classify SMS as a restricted out-of-band authenticator with significant telecom vulnerabilities. Yet even TOTP has important cryptographic limitations compared to modern hardware passkeys:
| Security Property | SMS OTP | Authenticator App (TOTP) | Passkey / Hardware Key (FIDO2 / WebAuthn) |
|---|---|---|---|
| Cryptographic Primitive | Random server code over cellular | Symmetric HMAC-SHA1/256 | Asymmetric Public-Key (ECDSA / Ed25519) |
| Works Offline / Airplane Mode | No | Yes | Yes |
| SIM-Swap & SS7 Resistance | Vulnerable | Immune | Immune |
| Server Database Breach Risk | N/A (ephemeral) | High if KMS key is compromised (Server stores decryptable seed K) | Immune (Server stores only a Public Key) |
| Real-Time Phishing Resistance | Low | Low (Vulnerable to AiTM reverse proxies) | Cryptographically Origin-Bound (AAL3) |
| Delivery Latency | 2 to 180+ seconds | Instant (Local calculation) | Instant (Local signature) |
1. The Vulnerabilities of SMS OTP
- SIM-Swapping: An attacker social-engineers or bribes a cellular carrier representative to port your phone number to an attacker-controlled SIM or eSIM. All subsequent SMS OTPs route directly to the attacker.
- SS7 and Diameter Roaming Exploits: Legacy signaling protocols that interconnect global cellular networks lack end-to-end cryptographic authentication, allowing well-resourced adversaries to redirect or intercept SMS traffic at international carrier interconnects.
- Mobile Malware & Notification Interception: Malicious apps granted notification-listener or SMS permissions on a compromised handset can silently exfiltrate incoming OTP texts.
2. Two Structural Limitations of TOTP (and Why Passkeys Solve Both)
While TOTP completely eliminates cellular carrier risks, security engineers must account for two fundamental limitations of symmetric six-digit codes:
- Symmetric Shared-Secret Storage on the Server: Unlike passwords—which a server hashes using a slow, irreversible one-way function like Argon2id or bcrypt—a TOTP shared secret K cannot be hashed one-way. Because the server must feed the raw bytes of K into HMAC(K, T) at every login, the server must store K in reversible encrypted form (protected by a Key Management Service or Hardware Security Module). If an attacker steals both the database of encrypted TOTP seeds and the server's decryption key (as happened in the 2011 RSA SecurID seed heist), the attacker can clone every user's authenticator indefinitely.
- Real-Time Adversary-in-the-Middle (AiTM) Reverse-Proxy Phishing:
A six-digit TOTP code contains no information about which website you are typing it into. If a user is tricked into visiting a lookalike phishing domain (
login-mybank.com) running a real-time reverse proxy (such as Evilginx), the proxy forwards the user's password and 6-digit TOTP code to the realmybank.comwithin milliseconds and steals the resulting session cookie.
The Asymmetric Solution: FIDO2 / WebAuthn Passkeys
To eliminate both server-side seed theft and reverse-proxy phishing, modern authentication is migrating to FIDO2 / WebAuthn Passkeys (built on the trapdoor mathematics explained in How Public-Key Cryptography Actually Works):
- During registration, your device's Secure Enclave or TPM generates an asymmetric keypair. The private key never leaves your hardware chip; the server receives only the public key. Even if the server's entire database is dumped publicly, no secret seeds exist to steal.
- During login, your browser passes the exact origin domain name from the TLS address bar into the hardware authenticator, which signs both the server's random challenge and the origin string. A signature generated on
login-mybank.comis mathematically invalid formybank.com, rendering real-time phishing proxies useless.
Why this matters
The enduring brilliance of TOTP lies in its minimal engineering footprint:
- It requires no network connectivity on the user's device.
- It requires no specialized hardware beyond a basic quartz clock and a 160-bit storage slot.
- It requires no per-login telecom fees or carrier routing dependencies.
By combining the steady progression of Unix epoch time with keyed cryptographic hashing, two completely disconnected devices on opposite sides of the planet can agree on a rotating six-digit proof of possession every thirty seconds.
To understand why telecommunication-based SMS OTPs frequently fail or get delayed inside cellular carrier networks, read the companion explainer on Why SMS OTPs Sometimes Arrive Late or Fail Entirely. You can also see how device-bound cryptographic keys secure real-time retail payments in How UPI Works.
How Digital Payments and Banking Infrastructure Work
Starting question: “When you tap a credit card or scan a UPI QR code and see "Payment Successful" in under two seconds, what messages actually travel across banking switches—and when does real money move between banks?”
Explains the shared-secret HMAC and time-step authentication principles used across banking security.
Where to Go From Here
Follow downstream mechanisms, contrasting architectures, or applications of these principles.
How Passkeys and WebAuthn Work
Why can't a passkey ever be phished by a fake website, and how does your phone log you into a computer without sending a password or biometric data across the internet?
How Public-Key Cryptography Actually Works
How can two complete strangers establish an unbreakable secret over an open wire where eavesdroppers hear every single word?
How Single Sign-On (SSO), OAuth 2.0, and OpenID Connect Work
How does 'Sign in with Google' or corporate SSO let you access third-party websites without ever revealing your actual password to those sites?
Why SMS OTPs Sometimes Arrive Late or Fail Entirely
Why does a one-time password sometimes take three minutes to arrive on your phone when an internet message arrives instantly?
Verified Specifications & Architectural References
This explainer is grounded in primary-source engineering specifications, regulatory circulars, and standard documentation.
RFC 6238: TOTP: Time-Based One-Time Password Algorithm
The official IETF standard specifying the TOTP algorithm, 30-second time step defaults, and HMAC-SHA-1 / SHA-256 / SHA-512 support.
RFC 4226: HOTP: An HMAC-Based One-Time Password Algorithm
Foundational counter-based OTP standard defining the dynamic truncation 31-bit extraction and modulo reduction algorithm.
NIST SP 800-63B: Digital Identity Guidelines (Authentication and Lifecycle Management)
Official federal security guidelines detailing PSTN/SMS out-of-band risks, symmetric cryptographic authenticators, and phishing-resistant AAL3 requirements.
Web Authentication: An API for Accessing Public Key Credentials (Level 2)
Official W3C standard specifying origin-bound public-key passkey authentication that eliminates shared-secret phishing and server seed theft.