Cryptography

🔐 TOTP vs HOTP: How Authenticator Apps Generate Time-Based Codes

By Security Research Team · 18 October 2026 · 8 min read · 1,540 words

Every authenticator app on the planet runs the same 60-year-old algorithm: HMAC-SHA1. The code that appears on your screen is not random. It is a deterministic, time-synchronized output derived from a shared secret you scanned into the app once and have not thought about since. Understanding exactly how that computation works tells you precisely what TOTP protects against, and what it does not.

TOTP (Time-Based One-Time Password) is a standard defined in RFC 6238 that generates a short numeric code by applying HMAC-SHA1 to a shared secret key and the current Unix timestamp divided into 30-second intervals. The code changes every 30 seconds and is valid only once per time step. Both the authenticator app and the server compute the same value independently, with no code ever transmitted during normal use.

What Is HOTP? The Original One-Time Password Standard

TOTP is a direct extension of an earlier standard called HOTP, published as RFC 4226 in 2005. HOTP stands for HMAC-Based One-Time Password. It works identically to TOTP except for one input: instead of a time value, it uses a counter.

The counter starts at zero when you register your authenticator. Each time you request a code, both your device and the server increment the counter by one. The code for counter value 7 is the same every time it is computed, but counter 7 is only ever used once. After use, both sides move to counter 8.

This design has a practical weakness. If you generate codes without using them (for example, accidentally pressing the button multiple times), your device's counter advances ahead of the server's. The server needs a look-ahead window, typically 10 to 100 steps, to stay synchronized. A wide look-ahead window means a stolen code from earlier in the sequence is still valid. The longer that window, the larger the attack surface.

According to NIST Special Publication 800-63B (Digital Identity Guidelines, section 5.1.4), counter-based OTP devices "must use hardware security to protect the secret key from unauthorized modification or extraction." The standard recommends time-based tokens for new deployments because they do not have the synchronization problem.

What Is TOTP? How Time Replaced the Counter

RFC 6238 (2011) modified HOTP by replacing the counter with a time step. The time step is computed as:

T = floor(Unix_timestamp / 30)

Every 30 seconds, this value increments by exactly 1. At 12:00:00 UTC, T might be 55,923,840. At 12:00:30, it becomes 55,923,841. Both your app and the authentication server compute HMAC-SHA1 using the same shared secret key and the same T value. If they agree, you are authenticated.

Neither party transmits the shared secret during login. The server already has it from your initial registration. This is the fundamental advantage over SMS: a text message containing "Your code is 847291" literally puts the secret in transit. TOTP sends nothing secret over the network at login time.

The Cryptography: HMAC, Shared Secrets, and Truncation

The computation inside every authenticator app has three steps:

Step 1: Compute the HMAC

The app runs HMAC-SHA1(K, T), where K is your 160-bit shared secret and T is the current time step encoded as an 8-byte big-endian integer. HMAC-SHA1 produces a 20-byte (160-bit) output. Some implementations use HMAC-SHA256 or HMAC-SHA512 for stronger hashing, though HMAC-SHA1 remains the default in RFC 6238 and is still considered secure for this application because the attacker never sees the HMAC output directly.

Step 2: Dynamic truncation

The app takes the last byte of the 20-byte HMAC output and reads its low-order 4 bits to determine an offset. It then extracts 4 bytes starting at that offset and strips the sign bit. This produces a 31-bit integer.

Step 3: Generate the digits

The 31-bit integer is reduced modulo 10^6 (for a 6-digit code) or modulo 10^8 (for 8 digits). That final value is zero-padded to the required length and displayed on screen.

The entire process is deterministic. Given the same K and the same T, every correctly implemented authenticator app on the planet produces the same code. The NCSC Authentication Guidance (2024) notes that "time-based one-time passwords provide a significant improvement over static passwords precisely because the valid code surface is collapsed to a single 30-second window, dramatically limiting the value of intercepted credentials."

Why 30 Seconds Is the Standard

RFC 6238 specifies 30 seconds as the default time step but allows servers to implement 60-second steps. The 30-second choice reflects a usability trade-off: short enough that a stolen code has very limited reuse time, long enough that users can read and type a 6-digit number without the clock flipping mid-entry.

In practice, most servers accept codes from the current time step and one step on either side. This means a code displayed in the last second of one 30-second window is still valid for the first second of the next. That tolerance window covers clock drift and user typing speed without meaningfully expanding the attack surface. The usable window is effectively 30 to 90 seconds in the worst case, not 30 seconds in isolation.

A 60-second step doubles that window. Some enterprise deployments use 60 seconds to reduce pressure on users who move slowly between screens, but the expanded window is a security regression for high-value accounts.

TOTP vs HOTP vs SMS: A Direct Comparison

PropertyTOTPHOTPSMS OTP
StandardRFC 6238RFC 4226Proprietary (carrier-dependent)
Code sourceHMAC-SHA1 + time stepHMAC-SHA1 + counterServer generates, transmits by SMS
Secret transmitted at login?NoNoYes (the code itself is the secret)
Code expiry30-60 secondsOn use (or look-ahead window)Typically 5-10 minutes
SIM swap vulnerable?NoNoYes
Real-time phishing vulnerable?Yes (within time window)Yes (within look-ahead)Yes (wider window)
Offline use?YesYesNo (requires cellular/data)
Synchronization dependencyClock (NTP)Counter (can desync)None

CISA's 2025 advisory on phishing-resistant MFA classifies TOTP as "phishing-resistant against passive interception but not against active proxying." SMS OTP receives a lower classification because the code travels over infrastructure (the cellular network and the SMS delivery provider) that neither the user nor the service controls. A SIM swap, an SS7 exploit, or a compromised SMS gateway all defeat SMS OTP at the network level before the code ever reaches the user's phone.

QR Codes and the Shared Secret Exchange

The shared secret K is a randomly generated 160-bit (20-byte) value created by the server when you register an authenticator. It is encoded in Base32 and embedded in an otpauth:// URI, which the QR code encodes. A typical URI looks like:

otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=SHA1&digits=6&period=30

When you scan the QR code, the authenticator app decodes the URI and stores the secret locally. That is the only moment the secret crosses a channel you control: from the server's screen to your device's camera. After that, the secret lives in your app's secure storage and is never transmitted again.

The implication is that if your QR code scan is observed (someone photographs your screen), the attacker has your shared secret permanently. They can generate valid codes for any future time step, indefinitely, on any device. Protect the QR code registration screen as carefully as you protect the password itself.

What TOTP Does Not Protect Against

TOTP is a significant step up from passwords alone or SMS OTP. It is not a complete defence.

Adversary-in-the-Middle (AiTM) phishing: A reverse proxy can capture a valid TOTP code and immediately relay it to the real server within the same 30-second window. Tools designed for this attack have been available since at least 2019 and are widely used in credential theft campaigns. CISA and the NSA's joint guidance on phishing-resistant MFA (2023) notes that TOTP and push notification MFA "can be defeated by sophisticated adversaries using real-time phishing proxies" and recommends FIDO2/WebAuthn hardware keys for the highest-risk accounts. FIDO2 is phishing-resistant by binding the authentication to the specific origin URL, so a proxy site on a different domain cannot relay the credential successfully.

Device compromise: If malware runs on the device hosting your authenticator app, it may extract the shared secret from secure storage. On rooted Android devices or jailbroken iPhones, the isolation guarantees of secure storage are weakened. An attacker with root access and your shared secret can generate valid codes indefinitely.

Backup code theft: When you set up TOTP, most services generate 8 to 10 single-use backup codes for account recovery if you lose your phone. These codes are as powerful as the TOTP secret. Store them in a password manager, not in a plain text file or a screenshot sitting in cloud photo storage.

Account recovery weakness: Many sites with TOTP enabled allow account recovery via email or phone number, effectively bypassing TOTP for anyone who controls those recovery channels. A strong TOTP setup is only as strong as its recovery path.

Backup Codes and Recovery

When you enable TOTP on a new service, download and store the backup codes before dismissing the setup screen. Most services will not show them again. Storing them well means:

If you use a password manager that supports TOTP storage natively, such as NordPass, the authenticator secrets and backup codes can live in the same zero-knowledge encrypted vault. The trade-off is that a compromised vault now exposes both your password and your second factor simultaneously. For most accounts, the usability improvement is worth it. For the most sensitive accounts (banking, primary email, domain registrar), a separate dedicated authenticator app on a different device is the stronger choice.

If you lose access to your authenticator app and your backup codes, account recovery falls back to whatever identity verification the service offers: government ID, billing information, or a trusted recovery email. None of these are as reliable as having your backup codes accessible.

Affiliate Disclosure: This post contains affiliate links. Purchases made through these links earn a small commission at no extra cost to you. Full disclosure.

FAQs

What is the difference between TOTP and HOTP?

HOTP uses a per-use counter; TOTP uses the current Unix timestamp divided into 30-second steps. HOTP codes remain valid until used, which creates a wider attack window if a code is stolen before it is consumed. TOTP codes expire automatically at the end of each 30-second interval, reducing that window substantially.

Can a TOTP code be intercepted and reused?

Yes, within the same 30-second window. Real-time phishing proxies capture TOTP codes entered on a fake site and relay them to the real site before the step expires. This is called an AiTM attack. Once the code is used, the server should reject a second submission of the same code for the same time step. The protection is the narrow window, not cryptographic uniqueness per use.

Why do some sites use 6-digit codes and others 8-digit codes?

Both are standard under RFC 6238. Six digits gives 1-in-1,000,000 brute-force odds per attempt within a 30-second window. Eight digits raises that to 1-in-100,000,000. High-security applications use 8 digits. Most consumer services use 6 digits because users are faster and less error-prone with shorter strings.

What happens if my phone clock is wrong?

TOTP codes are time-synchronized. If your device clock is off by more than 30 to 60 seconds from the server's clock, authentication fails. Most authenticator apps accept a one-step tolerance (plus or minus 30 seconds). If you see consistent authentication failures, check that your device is set to automatic (NTP-synced) time.

Is TOTP safe if my authenticator app is on the same phone as my password manager?

Combining both on one device is weaker than using separate devices, since a compromised phone exposes both factors at once. For most accounts, the convenience trade-off is acceptable. For high-value accounts, a dedicated hardware token or a separate low-risk device for TOTP provides cleaner factor separation.

Generate a Cryptographically Secure Password →
We use cookies to improve your experience. Learn more
admin