正在加载,请稍候…

One-Time Passwords: How OTPs Work and Why They Matter for Security

Understand the principles of HOTP and TOTP, common implementation pitfalls, and how to use an OTP generator for secure multi-factor authentication.

One-Time Passwords (OTPs) are a cornerstone of modern authentication, used for login, password reset, and transaction verification. But not all OTPs are equal, and poor implementation can turn a security feature into a vulnerability. This article explains the cryptographic principles behind HOTP and TOTP, highlights common pitfalls, and shows how to use an OTP generator effectively.

A smartphone displaying a 6-digit OTP code on a secure app interface

What Is an OTP?

A One-Time Password (OTP) is a temporary, single-use code that authenticates a user for a specific session or transaction. Unlike static passwords, OTPs expire quickly and cannot be reused, making them resistant to replay attacks.

OTPs are typically delivered via SMS, email, or generated by an authenticator app. However, the underlying algorithms — HOTP (HMAC-based One-Time Password) and TOTP (Time-based One-Time Password) — define how the code is derived.

HOTP vs. TOTP: The Core Algorithms

HOTP (RFC 4226)

HOTP uses a counter that increments with each successful authentication. The server and client share a secret key, and both compute the OTP as:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))

Where:

  • K is the shared secret.
  • C is an 8-byte counter value.
  • Truncate extracts a dynamic binary code and converts it to a decimal OTP of configurable length (typically 6–8 digits).

Pros: Works offline; no clock synchronization needed. Cons: Counter desynchronization if the user generates codes without authenticating (e.g., pressing "next" too many times).

TOTP (RFC 6238)

TOTP extends HOTP by replacing the counter with a time step (usually 30 seconds). The code is computed as:

TOTP(K, T) = HOTP(K, floor((current_time - T0) / X))

Where:

  • T0 is the Unix epoch (0) or a custom start time.
  • X is the time step (e.g., 30 seconds).

Pros: Automatically resynchronizes; no counter drift. Cons: Requires accurate clock; vulnerable to clock skew (typically ±1 step allowed).

Feature HOTP TOTP
Input Counter (incremented) Time (current Unix time)
Synchronization Manual (counter resync) Automatic (time-based)
Clock requirement None Requires accurate clock
Common use case Hardware tokens Authenticator apps

Why OTP Implementation Matters

A well-implemented OTP system provides strong multi-factor authentication (MFA). However, common mistakes can render it insecure. Research (e.g., OTP-Hunter, 2025) has identified four major vulnerability classes:

  1. OTP Bombing — Repeatedly sending OTPs to a target, causing annoyance or resource exhaustion.
  2. OTP Brute-Force — Enumerating short OTP codes (e.g., 4–6 digits) due to missing rate limiting.
  3. OTP Leakage — Exposing OTPs in logs, URLs, or API responses.
  4. Resource Consumption — Server-side DoS via excessive OTP generation requests.

The SIM Swap Threat

SMS-based OTPs are particularly vulnerable to SIM swap attacks, where an attacker tricks a carrier into transferring the victim's phone number to a new SIM. Once in control, the attacker receives all SMS OTPs. This has led regulators like the Philippines' BSP to mandate phasing out SMS OTPs by 2026.

Common Implementation Pitfalls

  • No rate limiting on OTP requests — Attackers can flood the server, causing denial of service or brute-force attempts.
  • Short OTP length — 4-digit codes offer only 10,000 combinations; with no rate limit, they can be brute-forced in minutes.
  • Predictable OTP seeds — Using weak random number generators (e.g., rand() instead of crypto/rand) makes the secret key guessable.
  • Storing OTPs in plaintext — Leaked databases expose active codes.
  • Ignoring clock skew — TOTP implementations must allow a window (e.g., ±1 time step) to account for clock drift, but too large a window weakens security.
  • No account lockout — After a few failed attempts, the account should be temporarily locked to prevent brute-force.

Worked Example: Generating and Verifying a TOTP

Let's walk through a complete example using Python (the pyotp library).

Step 1: Install the library

pip install pyotp

Step 2: Generate a secret key

import pyotp

# Generate a random base32 secret (16 characters = 80 bits)
secret = pyotp.random_base32()
print(f"Secret: {secret}")

Example output: JBSWY3DPEHPK3PXP

Step 3: Create a TOTP object and get the current code

totp = pyotp.TOTP(secret)
current_code = totp.now()
print(f"Current OTP: {current_code}")

Step 4: Verify the code

# Simulate user input
user_input = input("Enter OTP: ")

if totp.verify(user_input):
    print("Valid OTP")
else:
    print("Invalid OTP")

Step 5: Generate a QR code for the authenticator app

uri = totp.provisioning_uri(name="user@example.com", issuer_name="MyApp")
print(f"URI: {uri}")
# Use a QR code library (e.g., qrcode) to display this URI as a QR code.

The URI follows the otpauth:// scheme, which authenticator apps (Google Authenticator, Authy) can scan.

Using an OTP Generator Tool

Our OTP Generator lets you quickly generate HOTP/TOTP codes for testing or demonstration. You can specify the secret, algorithm, digits, and time step. This is especially useful for:

  • Debugging OTP integration in your app.
  • Generating test codes without setting up a full server.
  • Understanding how different parameters affect the output.

Security Best Practices

  1. Use TOTP over HOTP for most applications — time synchronization is easier than counter management.
  2. Enforce rate limiting on OTP generation and verification endpoints.
  3. Use at least 6-digit codes (8 digits recommended).
  4. Set a short OTP validity window (e.g., 30 seconds for TOTP, or 5 minutes for email OTPs).
  5. Never log OTPs in plaintext.
  6. Use cryptographically secure random for secret generation.
  7. Implement account lockout after 3–5 failed attempts.
  8. Consider push-based authentication (e.g., in-app OTP) to avoid SIM swap risks.

FAQ

What is the difference between HOTP and TOTP?

HOTP uses a counter that increments with each use, while TOTP uses the current time as input. TOTP is more common in authenticator apps because it auto-synchronizes without user action.

Can OTPs be brute-forced?

Yes, if no rate limiting is applied. A 6-digit code has 1 million combinations; with 1000 requests per second, it can be cracked in ~16 minutes. Rate limiting and account lockout are essential.

Why is SMS OTP considered insecure?

SMS OTPs are vulnerable to SIM swap attacks, SS7 interception, and phishing. Regulators are increasingly mandating alternatives like app-based OTPs or biometrics.

How long should an OTP be valid?

For TOTP, 30 seconds is standard. For email or SMS, 5–10 minutes is common. Longer windows increase the risk of interception.

What is a "cloud trigger" in OTP fuzzing?

A cloud trigger is the last function in the app's code where parameters (e.g., phone number, OTP) are still unencrypted or unsigned. Fuzzing at this point can bypass encryption and integrity checks, revealing vulnerabilities.