Autional logo
Tech 10 min #MFA#TOTP#FIDO2

Multi-Factor Authentication Protocol Comparison: TOTP vs HOTP vs FIDO2 vs SMS OTP

Multi-factor authentication (MFA) is the most effective defense against account takeover. Microsoft research shows MFA can block 99.9% of account compromises. But “MFA” is an umbrella term — the security gap between specific technical implementations is enormous.

This article puts four mainstream MFA protocols side by side, analyzing them layer by layer from the protocol level to the security level.

Quick Overview of the Four MFA Protocols

ProtocolYear IntroducedStandardAuthentication FactorInteraction
SMS OTP1990sNo unified standardSomething you have (phone number)Receive SMS, enter manually
HOTP2005RFC 4226Something you have (HMAC counter)Hardware token or App display, enter manually
TOTP2008RFC 6238Something you have (HMAC time-sync)App shows 6-digit code, enter manually
FIDO22018W3C + FIDOSomething you have (private key) + Something you are (biometric)USB/NFC/BLE tap, or fingerprint/face confirm

SMS OTP: The Weakest MFA, but the Most Widespread

How It Works

1. User enters phone number on login page
2. Server generates 4-6 digit random code, valid for 5 minutes
3. Server calls SMS gateway API to send the code to the user's phone
4. User receives SMS and enters the code
5. Server compares — match means pass

SMS OTP security relies on one assumption: a phone number can uniquely and securely identify a user. But in 2026, that assumption is very fragile.

Security Weaknesses

1. SIM Swap Attack

Attackers use social engineering to request a SIM replacement from the carrier, transferring the target’s phone number to a SIM card they control. Once successful, they can receive all SMS messages sent to that number — including MFA codes.

In 2024, the U.S. SEC’s X (formerly Twitter) account was compromised via SIM swap + SMS OTP hijacking.

2. SS7 Protocol Vulnerabilities

SS7 (Signaling System No. 7) is the signaling protocol between telecom carriers, designed in the 1970s with几乎没有 security considerations. Attackers with SS7 access (typically through compromised smaller foreign carriers or black-market access) can intercept or redirect SMS messages.

3. Phishing Attacks

Users can enter an SMS code on a phishing site, and the attacker immediately relays it to the real site. This real-time phishing works perfectly against SMS OTP — because SMS OTP has no origin binding.

4. No Encryption, No Integrity Protection

SMS messages travel in plaintext over carrier networks. Base stations, core network equipment, international signaling gateways — any node can eavesdrop.

Scorecard

DimensionScoreNotes
Security★★☆☆☆Vulnerable to SIM swap, SS7 hijacking, phishing
User Experience★★★☆☆Must wait for SMS delivery, poor experience with weak signal
Deployment Cost★★★★★Just an SMS gateway API, zero client deployment
Phishing Resistance★☆☆☆☆No origin binding, phishing sites can relay directly
Offline Usability★☆☆☆☆Depends on cellular network coverage

HOTP: Event-Based HMAC OTP

How It Works

HOTP (HMAC-based One-Time Password) uses a shared secret and an incrementing counter to generate one-time passwords:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))
Where:
  K = Shared secret (at least 128 bit, recommended 160 bit)
  C = 8-byte counter, increments after each use
  Truncate = Extract 6-8 decimal digits from HMAC result
Initialization:
  Server generates random secret K
  Server encodes K as URI or QR code (otpauth://hotp/...)
  User scans with App, App stores K, counter C initialized to 0

Authentication:
  Server sends challenge (waiting for user input)
  User presses hardware token button or App generate button
  App internally: C += 1, OTP = HOTP(K, C), display OTP
  User enters OTP
  Server: retrieves K and C from DB, computes OTP' = HOTP(K, C)
  If OTP == OTP', verification passes, C += 1

Counter sync issue:
  If the user accidentally presses the token (generates OTP but doesn't use it),
  the App's C and server's C become out of sync.
  Solution: server tries C, C+1, C+2... when verifying OTP
  (Window size configurable, typically 5-10)

Characteristics

HOTP’s defining feature is that it’s event-driven — each OTP generation requires active user action. This is both an advantage (works offline, no clock sync needed) and a disadvantage (accidental presses cause counter drift).

Best suited for: hardware security tokens providing one-time passwords for employees in offline environments.

Scorecard

DimensionScoreNotes
Security★★★☆☆HMAC-SHA1 cryptographic strength is adequate, but OTP can be phished
User Experience★★☆☆☆Must press button to generate, enter manually, counter sync issues
Deployment Cost★★★★☆Software App available, hardware tokens need distribution
Phishing Resistance★☆☆☆☆Like SMS OTP, OTP can be relayed
Offline Usability★★★★★No time sync needed, no network required

TOTP: Time-Based HMAC OTP

How It Works

TOTP (Time-based One-Time Password) is a time variant of HOTP — replacing the counter with the current timestamp:

TOTP(K, T) = HOTP(K, floor(T / X))
Where:
  K = Shared secret (typically 80 bit, Base32 encoded as 16 characters)
  T = Current Unix timestamp (seconds)
  X = Time step (typically 30 seconds)
Example:
  K = "JBSWY3DPEHPK3PXP" (Base32)
  T = 1715692800 (some Unix timestamp)
  X = 30 seconds
  
  C = floor(1715692800 / 30) = 57189760
  OTP = TOTP(K, T)
  
  Valid for [T, T+29] — 30-second window

This is how your familiar Authenticator Apps (Google Authenticator, Authy, Microsoft Authenticator) work. A 6-digit number refreshes every 30 seconds with no network connection required.

Security Hardening

Time Sync Tolerance

Client and server clocks can never be perfectly synchronized. Servers typically allow ±1 time step tolerance (allowing OTP from the previous or next 30-second window).

Replay Protection

Servers must remember recently verified OTPs to prevent reuse within the same 30-second window.

Autional mfa-service replay protection implementation:

func VerifyTOTP(userID, secret string, otp string) (bool, error) {
    now := time.Now().Unix()
    
    for offset := -1; offset <= 1; offset++ {
        t := now + int64(offset*30)
        expected := computeTOTP(secret, t)
        
        if otp == expected {
            key := fmt.Sprintf("totp:used:%s:%s:%d", userID, otp, t/30)
            if redis.Exists(key) {
                return false, ErrOTPReused
            }
            redis.Set(key, "1", 60*time.Second)
            return true, nil
        }
    }
    return false, nil
}

Scorecard

DimensionScoreNotes
Security★★★★☆Strong cryptography, auto-expires in 30s, but OTP still phishable
User Experience★★★★☆App auto-refreshes, copy-paste or autofill
Deployment Cost★★★★★Users just install a free App on their phone
Phishing Resistance★★☆☆☆30-second window helps, but real-time phishing can still relay
Offline Usability★★★★★Pure time calculation, no network needed

FIDO2/WebAuthn: The Strongest MFA

FIDO2 is fundamentally different from the first three MFA methods — it’s based on public-key cryptography, not shared secrets.

Core Difference

TOTP/HOTP/SMS OTP approach (shared secret):
  Server knows secret → generates expected OTP
  User knows secret → generates actual OTP
  If OTP matches → user holds correct secret

  ⚠ Problem: server stores the secret. If the server is breached, all secrets leak.

FIDO2 approach (public-key cryptography):
  User device generates key pair → private key stored securely in device → public key sent to server
  Server sends random challenge → device signs with private key → server verifies with public key

  ✅ Advantage: server only stores public keys. Even if the server is breached, attackers only get public keys.

Why FIDO2 Resists Phishing

Phishing attacks work by luring users to a fake site that looks identical to the real one, tricking them into entering credentials. But with FIDO2:

  1. The fake site’s domain differs from the real site
  2. The browser verifies the current page’s origin (protocol + domain + port) when calling the WebAuthn API
  3. rp.id is bound at registration time
  4. The authenticator checks whether the request’s rp.id matches the one from registration
  5. Mismatch → authenticator refuses to sign
  6. Even with a perfect phishing page, attackers can’t pass the authenticator

This is protocol-level phishing protection — not “advise users to check the URL,” but cryptographically impossible to authenticate under the wrong domain.

Scorecard

DimensionScoreNotes
Security★★★★★Public-key crypto + origin binding + hardware security chip
User Experience★★★★★One-tap fingerprint/face login, or insert key and tap
Deployment Cost★★★☆☆Requires server-side support and modern browsers (covering 95%+)
Phishing Resistance★★★★★Protocol-level origin binding, phishing sites can’t pass
Offline Usability★★★★☆No network needed during authentication (required during registration)

Comprehensive Comparison Matrix

DimensionSMS OTPHOTPTOTPFIDO2
Cryptographic BasisRandom numberHMAC-SHA1HMAC-SHA1ECDSA/EdDSA
Key StorageServer-sideShared both sidesShared both sidesPrivate key on device, public key on server
Phishing ResistanceNoneNoneVery weak (30s window)Strong (origin binding)
SIM Swap ResistanceNoneN/AN/AN/A
Offline UsabilityNo (needs cellular)YesYesYes
User InteractionWait for SMS → enterPress button → enterApp auto → enterBiometric / tap
Device DependencyPhone + SIM cardHardware token or AppAppPlatform authenticator or hardware key
Loss RiskSIM card damageToken damagePhone lossDevice loss
Recovery PlanReplace SIMBackup tokenBackup recovery codesAlternative auth method
Cost Per User~$0.007/msgToken ~$1-30FreeFree-$70
Security Score2/53/54/55/5
Recommended ForTransition or low-riskOffline industrialGeneral MFAHigh-security scenarios

Autional Multi-Channel MFA Architecture

Autional mfa-service manages all of the above MFA protocols in a unified way:

┌──────────────────────────────────────────────────┐
│                  mfa-service                       │
│                                                    │
│  ┌──────────┐  ┌──────────┐  ┌────────────────┐   │
│  │ SMS OTP  │  │   TOTP   │  │ FIDO2/WebAuthn │   │
│  │ Handler  │  │ Handler  │  │   Handler      │   │
│  └────┬─────┘  └────┬─────┘  └───────┬────────┘   │
│       │             │                │             │
│  ┌────▼─────────────▼────────────────▼──────────┐  │
│  │          MFA Policy Engine                    │  │
│  │  - Tenant-level MFA policy configuration     │  │
│  │  - User MFA registration management          │  │
│  │  - Adaptive auth strength selection          │  │
│  └──────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────┘

Multi-Channel Registration

Users can register multiple MFA methods simultaneously in their security settings:

{
  "user_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
  "mfa_methods": [
    {
      "type": "totp",
      "device_name": "iPhone Authenticator",
      "registered_at": "2026-01-15T10:30:00Z",
      "is_primary": false
    },
    {
      "type": "webauthn",
      "device_name": "YubiKey 5C NFC",
      "credential_id": "base64url...",
      "registered_at": "2026-03-22T14:00:00Z",
      "is_primary": true
    },
    {
      "type": "sms_otp",
      "phone_number": "+86138****8000",
      "registered_at": "2026-01-15T10:30:00Z",
      "is_primary": false
    }
  ],
  "backup_codes_remaining": 8
}

The system uses the user’s configured primary method by default, but automatically falls back to alternative methods if the primary one is unavailable (e.g., hardware key not nearby).

Adaptive MFA Policy

Autional’s adaptive MFA engine dynamically selects authentication methods based on login risk score:

Risk Score 0-30 (Low Risk):
  → User can log in with password, MFA not required

Risk Score 31-60 (Medium Risk):
  → Prompt user for TOTP verification

Risk Score 61-85 (High Risk):
  → Force FIDO2/WebAuthn verification
  → TOTP not accepted (may be phished)

Risk Score 86-100 (Critical Risk):
  → Deny login
  → Trigger security alert

Administrators can configure risk thresholds and corresponding authentication policies per tenant.

Selection Recommendations

ScenarioRecommended MFAReason
Consumer-facing SaaSTOTP (default) + FIDO2 (optional)Great UX, zero cost, high security
Enterprise internal systemsFIDO2 platform authenticator (Windows Hello / Touch ID)Easy device management, high security
Finance / BankingFIDO2 hardware key mandatoryHighest security, regulatory compliance
Offline industrial environmentHOTP hardware tokenNo network or time sync dependency
Temporary / transition solutionSMS OTPWide user coverage, but upgrade ASAP
Admin / privileged usersFIDO2 hardware key + TOTP backupDefense in depth, dual MFA channels

Summary

MFA is not an on/off switch — it’s a spectrum of security levels. From the weakest SMS OTP to the strongest FIDO2, the gap spans a dimension: shared secrets vs public-key cryptography, no origin binding vs protocol-level anti-phishing.

Autional mfa-service unifies all MFA protocols in one channel, so application developers don’t need to integrate each protocol separately. More importantly, the adaptive MFA engine ensures users don’t have to tolerate low-security authentication before they purchase hardware keys — the system automatically escalates authentication requirements based on risk.

MFA is the first line of defense for account security. Don’t settle for the weakest option.