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.
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
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$):
$$T = \left\lfloor \frac{\text{Current Unix Time} - T_0}{X} \right\rfloor$$
Where $T_0$ 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:
$$T = \lfloor 1,773,738,012 / 30 \rfloor = 59,124,600$$
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 and hashes it together with the secret key $K$ using HMAC-SHA-1 (or HMAC-SHA-256):
$$\text{HS} = \text{HMAC-SHA-1}(K, T)$$
HMAC ensures two properties:
- Irreversibility: You cannot infer the secret key $K$ by observing the hash digest $\text{HS}$.
- Avalanche Effect: A change of even one bit in the time counter $T$ completely and unpredictably scrambles the resulting 20-byte hash.
Step 4: Dynamic Truncation
The resulting hash $\text{HS}$ is 20 bytes (160 bits) long. A human cannot type a 40-character hexadecimal string every 30 seconds. The algorithm must safely compress this hash into six clean decimal digits.
To avoid mathematical bias, RFC 4226 specifies Dynamic Truncation:
- Take the very last byte of the 20-byte hash ($\text{HS}[19]$).
- Look at its lowest 4 bits (
HS[19] & 0x0F). This produces an offset between0and15. - Read 4 consecutive bytes from the hash starting at that offset: $$\text{Bytes} = \text{HS}[\text{offset} \dots \text{offset} + 3]$$
- Mask off the most significant bit (
& 0x7FFFFFFF) to ensure the number is treated as a positive 31-bit integer $P$. - Compute the integer modulo $10^6$: $$\text{Code} = P \pmod{1,000,000}$$
If $P = 348,912,419$, then $348,912,419 \pmod{1,000,000} = \mathbf{912419}$.
If the resulting number has fewer than six digits (e.g. 4819), the app pads the front with leading zeros (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 rigid 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 natural clock drift, RFC 6238 implementations implement a 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. This grants users a comfortable $\pm 30$-second margin of error.
Replay Attack Prevention
Allowing a 90-second window introduces a potential vulnerability: an eavesdropper who intercepts your six-digit code over an unencrypted local network could quickly re-use it before the 30-second window closes.
To prevent this, production authentication servers maintain a fast in-memory cache (such as Redis) of consumed tokens. Once a code is accepted for user Alice at counter $T = 59,124,600$, that counter value is marked as spent. If the exact same code is submitted two seconds later, the server immediately denies access.
SMS OTP vs. TOTP: The Attack Surface
While banks and consumer applications widely use SMS OTPs due to convenience, security professionals consider SMS the weakest form of two-factor authentication.
| Security Property | SMS OTP | Authenticator App (TOTP) | Hardware Key (FIDO2 / WebAuthn) |
|---|---|---|---|
| Network Dependent | Yes (Cellular / Carrier) | No (Pure Local Math) | No (Local USB/NFC) |
| Works in Airplane Mode | No | Yes | Yes |
| SIM-Swap Resistance | Vulnerable | Immune | Immune |
| SS7 Interception Risk | Vulnerable | Immune | Immune |
| Phishing Resistance | Low | Low (Can be typed into fake sites) | Absolute (Domain-bound) |
| Delivery Latency | 5 to 180+ seconds | Instant (Always displayed) | Instant |
The vulnerabilities of SMS OTP:
- SIM-Swapping: An attacker impersonates you, contacts your cellular carrier's support desk, and convinces them to transfer your phone number to a new SIM card. From that moment, all your SMS OTPs route directly to the attacker's handset.
- SS7 Signaling Exploits: The telecommunications protocol that routes text messages internationally (SS7) was designed in 1975 without modern cryptographic authentication. Sophisticated adversaries and surveillance vendors can intercept SMS messages mid-transit at telecommunications routing exchanges.
- Malware & Notification Scraping: Malicious Android apps with notification listener permissions can read incoming SMS verification codes without user intervention.
The Next Evolution: FIDO2 and Passkeys
While TOTP eliminates cellular carrier vulnerabilities, it still suffers from a critical weakness: Reverse-Proxy Phishing.
If an attacker sets up a clone of your bank's website (e.g., login-mybank.com), an automated phishing proxy (like Evilginx) can intercept both your password and your six-digit TOTP code in real time, immediately forwarding them to the real bank to establish a valid session cookie before the code expires.
To eradicate this vulnerability, the industry is transitioning to FIDO2 / WebAuthn Passkeys:
- Passkeys replace numbers with asymmetric public-key cryptography.
- Your device generates a private key that never leaves the hardware security chip.
- During authentication, the browser cryptographically signs a challenge incorporating the exact domain name in the address bar.
If you are on login-mybank.com, your browser signs a challenge bound to that malicious domain. When the attacker forwards that signature to mybank.com, the real bank's server detects the domain mismatch and immediately rejects the login.
Why this matters
The brilliance of TOTP lies in its radical simplicity:
- It requires no network connectivity.
- It requires no centralized verification authority.
- It requires no recurring cellular SMS fees for application developers.
By combining the universal, steady ticking of astronomical Unix time with the non-linear, irreversible properties of cryptographic hash functions, two computers located on opposite sides of the planet can reach mathematical consensus on a secret six-digit number every thirty seconds with zero communication between them.
To understand why telecommunication-based SMS OTPs frequently fail or get delayed when you need them most, explore the companion explainer on Why SMS OTPs Sometimes Arrive Late or Fail Entirely. You can also see how financial transaction security works in real-time banking in How UPI Works. To explore the foundational number theory and one-way trapdoors that make asymmetric keypairs, passkeys, and digital signatures mathematically unbreakable, see How Public-Key Cryptography Actually Works. To understand why telecommunication-based SMS OTPs frequently fail or get delayed when you need them most, explore the companion explainer on Why SMS OTPs Sometimes Arrive Late or Fail Entirely. You can also see how financial transaction security works in real-time banking in How UPI Works.
Where to Go From Here
Explore companion architectures or dive deeper into downstream mechanisms.
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?
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, time step defaults, and dynamic truncation method.
NIST SP 800-63B: Digital Identity Guidelines (Authentication and Lifecycle Management)
Official security guidelines detailing SMS out-of-band risks and multi-factor authenticator standards.