← Back to blog

Passkeys vs TOTP: The Cryptographic Shift from Shared Secrets to Public Key Signatures

PetexSpace

Authentication architectures across the web are undergoing the most significant paradigm shift in thirty years. For decades, user authentication relied upon knowledge-based shared secrets: primary passwords, complemented by secondary Time-Based One-Time Passwords (TOTP) specified in RFC 6238. While TOTP successfully mitigated offline credential stuffing and database password dumps, it exhibits a critical structural vulnerability: it remains vulnerable to modern Adversary-in-the-Middle (AiTM) real-time phishing proxies.

The emergence of Passkeys, built upon the FIDO2 and W3C Web Authentication (WebAuthn) open standards, fundamentally alters the cryptographic trust model. Passkeys replace symmetric shared secrets with public key cryptography, backed by hardware-isolated secure enclaves and mandatory cryptographic origin binding.

When architecting identity infrastructure, evaluating whether to migrate or maintain legacy secondary factors requires comparing the cryptographic threat surfaces. Engineers can evaluate TOTP shared secrets with privacy-preserving web tools to benchmark rotation behaviors, while evaluating browser execution profiles and measuring user verification latency using utilities to test hardware input latency.

1. The Trust Model Dilemma: Symmetric Secrets vs Asymmetric Key Pairs

The divergence between TOTP and Passkeys originates in their fundamental mathematical architectures.

   SYMMETRIC AUTHENTICATION MODEL (TOTP, RFC 6238)
   +-----------------------+                    +-----------------------+
   | Client Authenticator  |                    | Authentication Server |
   | Knows Shared Secret K |                    | Knows Shared Secret K |
   +-----------------------+                    +-----------------------+
               |                                            |
               v                                            v
     Calculate HMAC(K, T)                         Calculate HMAC(K, T)
               \                                            /
                +---------> Compare Tokens <---------------+
   Vulnerability: If the server database leaks, all user secrets are compromised.

   ASYMMETRIC AUTHENTICATION MODEL (Passkeys, FIDO2/WebAuthn)
   +-----------------------+                    +-----------------------+
   | Hardware Authenticator|                    | Relying Party Server  |
   | Private Key (d_A)     |                    | Public Key (Q_A)      |
   | Never leaves Enclave  |                    | Publicly shareable    |
   +-----------------------+                    +-----------------------+
               |                                            |
               v                                            v
     Signs Challenge & FQDN                       Verifies Signature via
     Signature = Sign(d_A, C)                     Verify(Q_A, Sig, C)
   Assurance: Server compromise reveals only public keys; private keys remain secure.

The Inherent Fragility of Symmetric Shared Secrets

Under RFC 6238 TOTP, authentication relies on a shared symmetric secret key KK. The client authenticator and the verification server must both maintain possession of the plaintext key.

This structure establishes a catastrophic single point of failure:

  • Server-Side Blast Radius: If an attacker compromises the authentication backend database, extracts database backups, or breaches memory caches, the attacker acquires every user's secret key KK. Armed with these seeds, the adversary can compute valid authentication codes indefinitely, completely bypassing multi-factor defenses without alerting end users.
  • Enrollment Interception: During initial provisioning, the secret key must be transmitted across the network (typically serialized as an otpauth:// URI inside an optical matrix barcode). Interception during this provisioning ceremony permanently compromises the credential.

The Asymmetric WebAuthn Paradigm

Passkeys eliminate shared secrets entirely by employing asymmetric public key cryptography over elliptic curves, typically:

  • P-256 (secp256r1): ECDSA using the NIST P-256 curve and SHA-256 (COSE algorithm identifier -7).
  • Ed25519: Edwards-curve Digital Signature Algorithm (COSE algorithm identifier -8).
  • RS256: RSA with PKCS#1 v1.5 padding and SHA-256 (COSE identifier -257, legacy compatibility).

During credential registration, the client hardware generates a unique, mathematically bound public-private key pair:

dA∈[1,n−1](Private Scalar Key)d_A \in [1, n-1] \quad (\text{Private Scalar Key}) QA=dA×G(Public Curve Point)Q_A = d_A \times G \quad (\text{Public Curve Point})

The private key dAd_A is generated directly inside a hardware-isolated security module (Apple Secure Enclave, Android Titan M, or a discrete TPM chip) and marked as non-exportable. Only the public key QAQ_A is transmitted over the wire to the Relying Party (the authentication server).

During subsequent logins, the server issues a random challenge. The client signs the challenge using dAd_A, and the server validates the signature using QAQ_A. If the server database is breached, the attacker acquires only public keys, which are mathematically useless for impersonating users.

2. Real-Time Adversarial Vectors: Phishing and Reverse Proxy Attacks

The decisive operational catalyst driving the transition to Passkeys is the commodification of Adversary-in-the-Middle (AiTM) phishing frameworks, exemplified by open-source toolkits such as Evilginx2 and Modlishka.

   ADVERSARY-IN-THE-MIDDLE (AiTM) ATTACK ON TOTP
   Victim Browser            Reverse Proxy (Attacker)         Legitimate Server
   (login.phish.com)         (login.phish.com)                (auth.legitimate.com)
         |                           |                                 |
         | --- 1. User & Pass -----> |                                 |
         |                           | --- 2. Relay User & Pass -----> |
         |                           | <-- 3. Prompt for TOTP -------- |
         | <-- 4. Display TOTP Form -|                                 |
         | --- 5. Types TOTP Code -> |                                 |
         |                           | --- 6. Relay TOTP Code -------> |
         |                           | <-- 7. Issue Session Cookie --- |
         |                           |    (Attacker Steals Cookie)     |
         | <-- 8. Redirect User -----|                                 |

Why TOTP Fails Against Reverse Proxies

TOTP codes possess no cryptographic binding to the transport session, the network socket, or the domain name displayed in the browser address bar. The generated 6-digit code is merely a function of time and the shared secret:

Token=f(K,T)\text{Token} = f(K, T)

When an attacker directs an employee or user to a phishing domain (such as login.petexspace-internal.com), the reverse proxy transparently forwards traffic to the legitimate server. When prompted for MFA, the user glances at their phone authenticator, reads the 6-digit code, and types it into the phishing page.

The proxy immediately relays the code to the legitimate backend, completes the authentication challenge, and intercepts the resulting session cookie. The multi-factor security guarantee collapses entirely because the user was fooled by the deceptive visual URL.

Cryptographic Origin Binding in WebAuthn

Passkeys completely neutralize AiTM phishing through cryptographic origin binding enforced at the browser engine level.

When a website invokes navigator.credentials.get(), the browser engine itself (not the web application JavaScript) inspects the document origin. It constructs a canonical data structure termed clientDataJSON:

{
  "type": "webauthn.get",
  "challenge": "dGhpcy1pcy1hLXNlY3VyZS1jaGFsbGVuZ2Utbm9uY2U",
  "origin": "https://auth.legitimate.com",
  "crossOrigin": false
}

The browser hashes clientDataJSON via SHA-256:

ClientDataHash=SHA-256(clientDataJSON)\text{ClientDataHash} = \text{SHA-256}(\text{clientDataJSON})

This hash, combined with authenticator data (authData, which contains the SHA-256 hash of the expected Relying Party ID), is passed down into the hardware security enclave:

SignedPayload=authData∥ClientDataHash\text{SignedPayload} = \text{authData} \parallel \text{ClientDataHash} Signature=SigndA(SignedPayload)\text{Signature} = \text{Sign}_{d_A}(\text{SignedPayload})
                    BROWSER ORIGIN VERIFICATION GATEWAY
   User visits: https://login.phish.com (Attacker Proxy)
   Application calls: navigator.credentials.get({ rpId: "legitimate.com" })
                            |
                            v
   [ Browser Engine Origin Security Check ]
   Does window.location.origin match rpId?
   "https://login.phish.com" != "https://legitimate.com"
                            |
                            +---> MISMATCH DETECTED:
                                  Browser terminates call immediately.
                                  Hardware authenticator is never invoked.
                                  Zero bytes transmitted to attacker proxy.

If an adversary hosts a phishing proxy at login.phish.com, the browser automatically populates "origin": "https://login.phish.com". If the proxy attempts to claim rpId: "legitimate.com", the browser security manager refuses to execute the request because the top-level origin does not match the requested RP ID.

Even if an attacker relays the signature payload to the legitimate backend, the legitimate server verifies that the signed origin matches its own domain. Because the signature covers the origin string, modifying the origin invalidates the cryptographic signature.

Phishing becomes mathematically impossible without compromising the browser binary itself.

3. WebAuthn Protocol Architecture and the Browser Pipeline

The WebAuthn specification defines two distinct cryptographic ceremonies: Registration (attestation) and Authentication (assertion).

   WEBAUTHN AUTHENTICATION CEREMONY
   Relying Party (Server)           User Agent (Browser)           Authenticator Enclave
           |                                  |                              |
           | -- 1. Challenge & RP ID -------> |                              |
           |                                  | -- 2. Collect Biometric ---> |
           |                                  |    (Touch ID / YubiKey)      |
           |                                  |                              |
           |                                  | <-- 3. Sign Hash ----------- |
           |                                  |    authData + clientDataHash |
           | <-- 4. Return Credential --------|                              |
           |    (Signature, authData, JSON)   |                              |
           v                                  v                              v
   [ Verify Signature using Public Key ]
   [ Check RP ID Hash, Origin, & Counter ]

The Registration Ceremony (navigator.credentials.create)

  1. The server generates a cryptographically secure random challenge (minimum 32 bytes) via OS entropy and transmits it along with the Relying Party configuration:
const credentialCreationOptions: CredentialCreationOptions = {
  publicKey: {
    challenge: new Uint8Array([/* 32 bytes */]),
    rp: { name: "PetexSpace", id: "petexspace.com" },
    user: {
      id: new Uint8Array([/* unique user uuid bytes */]),
      name: "[email protected]",
      displayName: "Security Architect"
    },
    pubKeyCredParams: [
      { alg: -7, type: "public-key" },  // ES256 (P-256)
      { alg: -257, type: "public-key" } // RS256
    ],
    authenticatorSelection: {
      authenticatorAttachment: "platform",
      userVerification: "required",
      residentKey: "required"
    },
    timeout: 60000
  }
};
  1. The user agent prompts the user to authorize registration (via biometric Touch ID, Face ID, or a hardware security key).
  2. The authenticator generates the asymmetric key pair, stores the private key within hardware storage, and returns an Attestation Object containing the public key encoded in Concise Binary Object Representation (CBOR).
  3. The server parses the public key, stores it in the database associated with user.id, and completes registration.

The Authentication Ceremony (navigator.credentials.get)

When the user attempts to sign in:

  1. The server issues a fresh challenge nonce.
  2. The browser invokes navigator.credentials.get().
  3. The authenticator prompts for user verification (biometric match or device PIN), increments an internal monotonically increasing signature counter, and computes the ECDSA signature over authData || SHA-256(clientDataJSON).
  4. The server receives the payload, verifies the digital signature against the stored public key point QAQ_A, confirms that clientDataJSON.origin matches the server origin, and verifies that the signature counter has incremented (detecting authenticator cloning).

4. Operational Trade-Offs: Recovery, Multi-Device Sync, and Enterprise Auditing

While Passkeys present overwhelming security advantages, they introduce novel engineering trade-offs regarding credential synchronization and disaster recovery.

+-----------------------------------------------------------------------------------------+
|                                PASSKEY TYPOLOGIES                                       |
+-----------------------------------------------------------------------------------------+
|  SYNCED PASSKEYS (Multi-Device)              |  DEVICE-BOUND PASSKEYS (Hardware Isolated)|
|  - Backed up in cloud keychains              |  - Stored strictly in non-exportable chip |
|  - Synced across Apple/Google ecosystem      |  - Bound to physical token (YubiKey 5)   |
|  - High usability, consumer-friendly         |  - Enterprise zero-trust compliant        |
|  - Recovery delegated to ecosystem vendor    |  - High operational loss management cost  |
+-----------------------------------------------------------------------------------------+

Synced Passkeys vs Device-Bound Hardware Keys

The modern Passkey initiative resolves user onboarding friction through multi-device synchronization:

  • Synced Passkeys (Consumer Tier): Managed through cloud-synchronized keychains (Apple iCloud Keychain, Google Password Manager, 1Password). Private keys are end-to-end encrypted in transit and replicated across all personal devices linked to that identity. If a user drops their iPhone in the ocean, purchasing a new device and authenticating to iCloud restores access to all registered credentials.
  • Device-Bound Passkeys (Enterprise Tier): Enforced by high-assurance security policies (e.g., FIDO2 Level 2/3 hardware authenticators like YubiKeys). The private key can never be extracted or synchronized across devices. If the physical key is lost, access is completely severed unless an explicit secondary physical token was registered in advance.

The Recovery Paradox

In a pure passwordless architecture using device-bound keys, account recovery represents the primary vulnerability vector. If an identity platform falls back to sending a password reset link via email or SMS when a user misplaces their key, an attacker will bypass the phishing-resistant Passkey entirely by targeting the weaker recovery channel.

Enterprise architectures mitigate this through strict identity proofs: requiring dual-custody administrator verification, issuing temporary hardware access codes, or requiring users to register a minimum of two independent physical authenticators before activating passwordless enforcement.

5. The Coexistence Strategy: Integrating TOTP and Passkeys in Modern Stacks

Given the billions of deployed legacy devices, systems lacking WebAuthn-compliant platform authenticators, and headless CLI environments, complete immediate deprecation of TOTP is impractical. Engineering teams must adopt a pragmatic coexistence strategy.

                    PROGRESSIVE AUTHENTICATION PIPELINE
   Incoming Authentication Request
                 |
                 v
   Does Client Support WebAuthn / Passkeys?
        |                              |
       YES                             NO
        |                              |
        v                              v
   [ Tier 1: Primary Authentication ]  [ Tier 2: Legacy Fallback ]
   FIDO2 Passkey Ceremony              Primary Password
   Phishing-Resistant ECDSA Signature  + RFC 6238 TOTP Secondary Code
        |                              |
        +--------------+---------------+
                       |
                       v
         [ Cryptographic Access Token Issued ]

Progressive Authentication Tiering

  1. Promote Passkeys as the Primary Phishing-Resistant Channel: Offer biometric passkey login on all modern browser interfaces. Seamless auto-fill (webauthn autocomplete) enables frictionless zero-click authentication.
  2. Retain RFC 6238 TOTP as a Durable Secondary Fallback: For air-gapped systems, continuous integration (CI/CD) pipelines, automated server daemons, and older mobile devices, retain TOTP as a hardened second factor. Because TOTP operates purely on time and arithmetic without browser API dependencies, it remains exceptionally reliable for headless automation.
  3. Audit Implementation Boundaries with In-Browser Execution: Ensure development teams verify token algorithms and credential decoders client-side. Inspecting seed URIs and verifying Base32 keys using tools like the PetexSpace /2fa-code-generator ensures zero network exposure of sensitive operational seeds during testing.

Cryptographic Comparison Summary

Security & Architectural DimensionRFC 6238 TOTPFIDO2 / WebAuthn Passkeys
Cryptographic PrimitiveSymmetric HMAC (SHA-1 / SHA-256)Asymmetric Public Key (P-256 ECDSA, Ed25519)
Secret Storage LocationBoth Client Device & Server DatabaseClient Hardware Security Enclave Only
Server Compromise ImpactTotal compromise (Seeds exposed)Zero impact (Only public keys exposed)
Phishing ResistanceVulnerable to AiTM Proxies (Evilginx2)Complete Mathematical Immunity (Origin Bound)
Hardware DependencyNone (Runs on any processor clock)Requires TPM / Secure Enclave / Security Key
CLI / Headless UsabilityExcellent (Simple string input)Complex (Requires FIDO2 HID pass-through)
Recovery ModelManual re-entry of Base32 seedEcosystem Cloud Keychain or Backup Token

By transitioning primary user authentication flows to WebAuthn Passkeys while maintaining mathematically verified RFC 6238 TOTP fallbacks, systems architects establish resilient, defense-in-depth security architectures that withstand the most sophisticated adversary attacks.