Two-factor authentication (2FA) requires evidence from exactly two independent factor categories: knowledge, possession, or inherence. MFA means two or more. A password plus a second password is still one factor; a password plus a TOTP authenticator combines knowledge and possession.

The engineering boundary includes enrollment and recovery. A phishing-resistant authenticator does not protect an account whose help desk can remove it after answering weak questions.

Method tradeoffs

MethodProofPhishing and replayRecovery boundaryChoose it when
SMS OTPControl of a phone-number delivery pathCode is phishable; SIM swap and carrier interception add riskPhone-number recovery can transfer controlExisting users/devices make a stronger factor unavailable
TOTPPossession of a shared authenticator secretCode is phishable and valid inside the accepted time windowBackup codes or replacement authenticator must be protectedBroad offline authenticator compatibility matters
Push approvalControl of an enrolled app/deviceGeneric approve/deny prompts enable fatigue attacksDevice enrollment and support reset are criticalEnterprise context/number matching is enforced
WebAuthn security keyPrivate key unlocked on an external authenticatorOrigin-bound signature over a fresh challengeSpare key or controlled reenrollment is neededHigh-assurance, portable phishing resistance matters
Synced passkeyDiscoverable WebAuthn credential available through a platform accountSame origin binding; sync-provider account becomes part of recovery trustPlatform sync and account recovery restore credentialsConsumer passwordless UX across devices matters

Default to passkeys/WebAuthn when the client population supports them. Keep TOTP as a compatibility fallback when needed, and protect fallback and recovery at least as carefully as primary enrollment. Avoid SMS for new high-value systems.

TOTP

TOTP derives a short code from a shared secret and a time-step counter. The server accepts only a small clock-skew window, rate-limits guesses, and records the last accepted step to reject replay. See TOTP for provisioning, validation, secret storage, and recovery mechanics.

FIDO2 and WebAuthn

WebAuthn defines the browser/API ceremony between a relying party (RP), client, and authenticator. CTAP defines communication with roaming authenticators such as security keys. A passkey is a WebAuthn discoverable credential: the authenticator can identify an account without the user first typing a username.

Registration ceremony

RP -> Browser: challenge, rp.id, user.id, credential options
Browser: enforce the caller-origin / RP-ID relationship and collect user consent/verification.
Authenticator: create a credential key pair scoped to rp.id
Authenticator -> Browser: authenticator data + attestation statement
Browser -> RP:
  credential ID
  response.clientDataJSON containing type, challenge, and origin
  response.attestationObject containing fmt, authData (authenticatorData), and attStmt
RP: validate challenge, origin, RP ID hash, flags, algorithm, and credential public key
RP: validate the attestation statement and trust path only when attestation policy requires it
RP: store credential ID, public key, user binding, and metadata

The attested credential data inside authenticatorData carries the credential ID and credential public key. With none attestation, the attestation statement can be empty and no attestation signature is returned; the RP still validates the client data, authenticator data, and public key. Other attestation formats may sign the authenticator data plus the hash of clientDataJSON, but the RP verifies that evidence only when its enrollment policy asks for attestation. The private key remains under authenticator control. The RP stores a public key, so a database leak does not directly reveal a reusable authentication secret. Registration must be authorized by a recent trusted session; otherwise an attacker who briefly controls an account can enroll their own credential.

Authentication ceremony

RP -> Browser: fresh unpredictable challenge + rp.id + allowed credentials or discoverable request
Browser: enforce the caller-origin / RP-ID relationship, build clientDataJSON, and invoke an authenticator for rp.id
Authenticator: verify user presence/verification, build authenticatorData with the RP-ID hash, and sign authenticatorData + SHA-256(clientDataJSON)
Browser -> RP: credential ID, authenticatorData, clientDataJSON, signature, optional user handle
RP: validate clientDataJSON type/challenge/origin, authenticatorData RP-ID hash/flags, signature, and credential/user binding
RP: consume the challenge once and create or elevate a session

Origin and RP-ID binding give WebAuthn its phishing resistance: a credential registered for example.com will not sign a challenge for examp1e.com. The fresh challenge and one-time server state stop replay. User verification such as a device PIN or biometric unlocks the authenticator; the biometric is not sent to the website.

Passkey, sync, and attestation choices

ChoiceBenefitCost / trust introduced
Device-bound credentialKey does not leave one authenticatorLost device requires another credential or recovery
Synced passkeyWorks across devices and survives device replacementPlatform account, encrypted sync, and its recovery become part of the trust model
Discoverable credentialUsername-less account selectionAccount-discovery UX and privacy need deliberate design
Attestation requiredCan restrict enrollment to approved authenticator models in managed environmentsReduces consumer compatibility and can add identifying metadata
Attestation not requiredBroad compatibility and less device metadataRP cannot enforce a hardware provenance policy

Attestation says something about the authenticator at registration; it does not establish the human’s legal identity and is not required for ordinary consumer passkeys. Decide it from the relying party’s assurance policy, not from a blanket belief that more attestation is always safer.

Failure and recovery behavior

  • Expire and consume WebAuthn challenges once, and bind them to the initiating session and intended ceremony.
  • Validate origin and RP ID on the server through a maintained WebAuthn library; never trust client-provided account identity without matching the stored credential binding.
  • Signature counters can signal some cloned authenticators, but zero or non-increasing counters are valid for some implementations. Treat counter anomalies according to authenticator behavior and risk policy, not as the sole replay defense.
  • Require recent strong authentication to add or remove a credential. Notify the user and expose named-device/credential revocation.
  • Offer multiple credentials or protected recovery codes before loss occurs. A TOTP/SMS fallback restores the fallback’s phishing resistance, not WebAuthn’s.
  • After high-risk recovery, revoke sessions, rotate recovery material, and apply a delay or additional review to sensitive actions where appropriate.

Questions

References