How Passkeys and WebAuthn Work
From FIDO2 public-key credentials and Secure Enclave isolation to origin binding, challenge-response signatures, and synced passkeys
“Why can't a passkey ever be phished by a fake website, and how does your phone log you into a computer without sending a password or biometric data across the internet?”
Passkeys and the W3C WebAuthn standard replace shared secrets and passwords with asymmetric public-key cryptography bound to hardware security modules. When you authenticate, your device signs a cryptographic server challenge inside an isolated Secure Enclave. Because the browser cryptographically binds the signature to the exact website origin (RP ID), even the most sophisticated lookalike phishing site cannot capture or reuse the credential.
- Why are passwords, SMS OTPs, and even authenticator apps vulnerable to modern adversary-in-the-middle (AiTM) phishing?
- What is the architectural difference between FIDO2, WebAuthn, and CTAP2?
- What happens inside a device's Secure Enclave / TPM during passkey registration?
- How does the Relying Party ID (RP ID) origin-binding mechanism mathematically make phishing impossible?
- What exact binary data is signed during authentication, and why is biometric data (Face ID, fingerprint) never sent to the server?
- How do synced passkeys (iCloud Keychain, Google Password Manager) work across multiple devices while remaining end-to-end encrypted?
- What is the difference between a multi-device synced passkey and a device-bound physical hardware security key (YubiKey)?
- How does cross-device authentication (scanning a QR code on a PC with a phone) establish an encrypted local Bluetooth/WebRTC handshake via FIDO Cross-Device Authentication (hybrid transport)?
To build a complete first-principles mental model of this mechanism, we recommend starting with these foundational explainers:
Every time you type a password into a website, you are transmitting a shared secret.
Both you and the server must know that secret. Even if the server hashes the password with salt and Argon2, and even if your connection is protected by TLS encryption, the shared secret model carries a fatal structural flaw: the human user decides where to send it.
If an attacker tricks you into visiting paypa1.com instead of paypal.com—or uses a modern reverse-proxy phishing framework like Evilginx to stand between you and the real site—your browser obediently hands your password and even your real-time 6-digit TOTP code to the attacker. The proxy forwards those credentials to the real server, steals your authenticated session cookie, and bypasses your two-factor authentication entirely. Over 80% of corporate data breaches originate from phished, stolen, or weak credentials.
Passkeys and the W3C WebAuthn / FIDO2 standard solve this not by making passwords longer or adding more confirmation steps, but by completely eliminating shared secrets.
When you create a passkey, your device generates an asymmetric cryptographic key pair: a public key sent to the website, and a private key sealed inside your device's isolated hardware security module. When you sign in, the server issues a random mathematical challenge. Your device signs that challenge using its private key and sends the signature back.
Crucially, the browser itself binds that signature to the exact domain name in the address bar. A fake website can look identical down to every pixel, but it cannot change its cryptographic domain origin. The math makes credential phishing physically impossible.
+----------------------------------------------------------------------------------------------------+
| THE WEBAUTHN / FIDO2 ARCHITECTURE |
| |
| 1. Relying Party (Server) 2. User Agent (Browser) 3. Authenticator (Hardware) |
| Sends random challenge & Enforces origin boundary Generates & stores private keys |
| stores ONLY public keys Validates RP ID = domain Inside Secure Enclave / TPM |
| │ │ │ |
| ▼ ▼ ▼ |
| 4. Asymmetric Cryptography 5. Origin Binding 6. User Verification |
| Signature proves possession Signature mathematically Biometric scan unlocks key |
| without revealing secret invalid on phishing domains Biometrics NEVER leave device |
+----------------------------------------------------------------------------------------------------+
1. Why Passwords and Authenticator Apps Can Be Phished
To appreciate why passkeys exist, we must dissect the vulnerability of legacy multi-factor authentication (MFA).
The Shared Secret Paradigm
Traditional authentication relies on three shared secrets:
- Passwords: A shared static secret (S) typed by the user and verified by the server: Hash(S) stackrel?= StoredHash.
- SMS OTPs: A shared temporary 6-digit secret transmitted across cellular SS7 signaling networks, vulnerable to SIM swapping and cell-tower interception.
- Authenticator Apps (TOTP - RFC 6238): A shared secret seed (K) provisioned via QR code. Both the phone and server hash K with the current 30-second Unix time counter:
While TOTP eliminates cellular transmission vulnerabilities, it does not eliminate human transmission vulnerabilities.
Adversary-in-the-Middle (AiTM) Phishing
In a modern AiTM attack, an attacker buys a lookalike domain (e.g., login-microsoft-auth.com) and deploys a transparent reverse proxy (such as Evilginx or Modlishka):
User Browser Attacker Proxy (Fake Domain) Real Service (Real Domain)
│ │ │
│ ─── 1. Types Password & TOTP Code ────► │ │
│ │ ─── 2. Forwards Password & TOTP ──────► │
│ │ │
│ │ ◄── 3. Returns Session Cookie (Auth OK) ┤
│ ◄── 4. Forwards Session Cookie ──────── │ │
│ (Attacker STORES a copy of session cookie; full account takeover achieved) │
Because the user sees a valid TLS padlock for login-microsoft-auth.com and the real Microsoft server receives the correct password and active 6-digit TOTP within its 30-second window, the authentication succeeds. The attacker intercepts the HTTP session cookie (Set-Cookie: session_id=xyz...) and gains permanent access, rendering passwords and TOTP codes useless against targeted phishing.
The only way to defeat AiTM phishing is cryptographic origin binding: the authentication response must be mathematically bound to the cryptographic domain identity of the server, verified by the client software (the browser) rather than the fallible human eye.
2. The FIDO2 and WebAuthn Standard Stack
Passkeys are built upon the open standard suite created by the FIDO Alliance (Fast IDentity Online) and standardized by the World Wide Web Consortium (W3C).
The architecture consists of three interlocking layers:
+──────────────────────────────────────────────────────────────────────────────────────────────────+
| FIDO2 / WEBAUTHN STACK |
+──────────────────────────────────────────────────────────────────────────────────────────────────+
| Web Application (JavaScript) |
| Calls navigator.credentials.create() and navigator.credentials.get() |
| ▲ |
| │ (W3C WebAuthn API Specification) |
| ▼ |
| User Agent / Browser Engine (Chrome, Safari, Firefox, Edge) |
| Validates origin, enforces RP ID constraints, constructs clientDataJSON |
| ▲ |
| │ (CTAP2 - Client to Authenticator Protocol) |
| ▼ |
| Authenticator (Secure Hardware) |
| • Platform Authenticator: Apple Secure Enclave, Android KeyStore / StrongBox, Windows Hello TPM |
| • Roaming Authenticator: Hardware USB/NFC Security Keys (YubiKey, Nitrokey) |
+──────────────────────────────────────────────────────────────────────────────────────────────────+
- W3C WebAuthn: A standardized JavaScript API exposed to web pages via
window.navigator.credentials. It allows a website to request public-key credential creation and challenge assertion without ever touching private keys. - FIDO CTAP2 (Client to Authenticator Protocol): The binary communication protocol that allows the web browser to talk to the underlying security hardware—whether an internal chip on the motherboard or an external USB/NFC security key.
- Relying Party (RP): The server hosting the web application (e.g.,
github.comorgoogle.com) that registers public keys and verifies cryptographic assertions.
3. The Registration Ceremony: Creating a Passkey
When a user clicks "Create a Passkey" on a website, the browser and hardware authenticator execute the Registration Ceremony.
User Device (Browser + Secure Enclave) Relying Party (Server)
│ │
│ ────────────── 1. Request Registration Options ───────────────────► │
│ │
│ ◄───────────── 2. Return Challenge + RP ID + User Info ──────────── │
│ │
[Browser checks Origin] │
Origin: "https://example.com" │
RP ID: "example.com" │
│ │
[Prompt Biometric Scan] │
User touches Touch ID / Face ID │
│ │
[Secure Enclave Action] │
Generates key pair: (sk_user, pk_user) │
Signs (authenticatorData + clientDataHash) │
│ │
│ ────────────── 3. Send Attestation Object + Credential ID ────────► │
│ │
│ [Server Verifies]
│ Checks signature
│ Stores Public Key
│ Stores Credential ID
Step 1: Server Generates Challenge and Parameters
The relying party server generates a cryptographically secure random challenge (minimum 16 bytes, typically 32 bytes from /dev/urandom) and returns a JSON configuration:
{
"challenge": "dGhpcy1pcy1hLXJhbmRvbS1zZXJ2ZXItY2hhbGxlbmdl",
"rp": {
"name": "Acme Corp",
"id": "acme.com"
},
"user": {
"id": "dXNlcl8xMjM0NQ",
"name": "alex@example.com",
"displayName": "Alex Rivera"
},
"pubKeyCredParams": [
{ "type": "public-key", "alg": -7 }, // ES256 (ECDSA over P-256 with SHA-256)
{ "type": "public-key", "alg": -257 } // RS256 (RSA with SHA-256)
],
"authenticatorSelection": {
"authenticatorAttachment": "platform",
"userVerification": "required",
"residentKey": "required"
},
"timeout": 60000
}
Step 2: Browser Enforces Origin and Prepares clientDataJSON
The web browser receives these parameters. Before contacting any hardware, the browser inspects its current URL:
- If the browser is on
https://acme.com/settings, it verifies that the requestedrp.id("acme.com") is a valid domain suffix of the current origin. - If an attacker hosts the page on
https://evil-phish.com, but setsrp.id: "acme.com", the browser immediately rejects the call. JavaScript cannot spoof the browser's knowledge of its own URL bar.
The browser constructs a canonical JSON structure called clientDataJSON:
{
"type": "webauthn.create",
"challenge": "dGhpcy1pcy1hLXJhbmRvbS1zZXJ2ZXItY2hhbGxlbmdl",
"origin": "https://acme.com",
"crossOrigin": false
}
It then calculates the SHA-256 cryptographic digest of this payload:
Step 3: Secure Hardware Generates Asymmetric Key Pair
The browser passes the clientDataHash, the rp.id, and user requirements to the platform authenticator via CTAP2.
The user is prompted for local authentication (Touch ID, Face ID, Windows Hello PIN, or Android fingerprint). This biometric scan never leaves the local operating system sandbox; it merely sends an electrical signal within the chip unlocking the Secure Enclave.
Once unlocked, the hardware random number generator creates a brand-new asymmetric key pair specifically for this domain:
- Private Key (skcred): Typically an elliptic curve key (e.g., NIST P-256 or Ed25519). It is stored in encrypted non-volatile memory locked to the Secure Enclave and can never be exported in plaintext.
- Public Key (pkcred): The corresponding mathematical point on the curve:
Step 4: The Authenticator Packages the Attestation Object
The authenticator packages the public key into an authenticatorData binary structure, appends an attestation signature, and returns it to the browser. The browser transmits:
credentialId: A unique random identifier pointing to this specific key pair.clientDataJSON: The raw JSON containing the origin and server challenge.attestationObject: Binary CBOR structure containing the public key (pkcred) and flags.
The server verifies that clientDataJSON.origin matches https://acme.com, verifies the challenge matches the one it issued, and saves the credentialId and publicKey in its database. The server stores zero passwords, zero hashes, and zero secrets. If the server's database is breached, the attacker gains only public keys, which cannot authenticate anyone.
4. The Authentication Ceremony: Cryptographic Challenge-Response
When the user returns to sign in, they execute the Authentication Ceremony.
Step 1: Server Sends Authentication Challenge
The server calls navigator.credentials.get() with:
- A new 32-byte random challenge.
rpId:"acme.com".- Optionally, a list of allowed
credentialIdvalues (or an empty list if using a discoverable passkey / resident key).
Step 2: Browser Origin Binding
The browser constructs a new clientDataJSON:
{
"type": "webauthn.get",
"challenge": "bmV3LXJhbmRvbS1sb2dpbi1jaGFsbGVuZ2UtOTg3Ng",
"origin": "https://acme.com",
"crossOrigin": false
}
The browser hashes this object:
Step 3: Hardware Signs the Authentication Assertion
The authenticator verifies the user's presence via biometrics or PIN. It constructs a 37-byte (or larger) binary structure called authenticatorData:
+────────────────────────┬───────┬─────────────────┬────────────────────────+
| rpIdHash (32 bytes) | Flags | SignCount (4 B) | Extension Data (opt) |
| SHA-256("acme.com") | (1 B) | Monotonic int | Custom extensions |
+────────────────────────┴───────┴─────────────────┴────────────────────────+
The Flags byte encodes crucial hardware-verified security bits:
- Bit 0 (UP - User Present): Set to
1if a physical touch was detected. - Bit 2 (UV - User Verified): Set to
1if a full biometric scan or PIN succeeded (not just a dumb button press). - Bit 6 (AT - Attestation): Indicates whether attestation data is included.
The authenticator concatenates these two binary blobs:
It signs M using the private key skcred via the ECDSA algorithm:
Where:
- k ∈R [1, n−1] is an ephemeral random nonce.
- (x1, y1) = k · G.
- r = x1 pmod n.
- s = k−1 (SHA-256(M) + r · skcred) pmod n.
Step 4: Server Cryptographic Verification
The browser sends the signature σ, authenticatorData, clientDataJSON, and credentialId to the server.
The server performs four non-negotiable checks:
- Challenge Verification: Decodes
clientDataJSONand verifies the challenge matches the one issued in Step 1. - Origin Verification: Verifies
clientDataJSON.originmatches the server's expected HTTPS origin (https://acme.com). - RP ID Hash Verification: Hashes its own expected domain name (SHA-256("acme.com")) and asserts it is byte-for-byte identical to the first 32 bytes of
authenticatorData. - Signature Verification: Retrieves the user's stored public key pkcred from the database and verifies the ECDSA signature:
If valid, the server logs the user in. No secret ever traversed the wire. No password was evaluated.
5. Why Phishing Is Mathematically Impossible
To see why passkeys cannot be phished, let us walk through what happens when an attacker attempts the classic Evilginx reverse-proxy attack:
Victim clicks phishing link: https://acme-login.attacker-phish.com
1. Phishing Server 2. Victim's Browser 3. Secure Enclave
Demands passkey login Sees URL in address bar: Receives RP ID:
Forwarding challenge from "https://acme-login.attacker-phish" "attacker-phish.com"
real Acme.com
│ │ │
▼ ▼ ▼
Attacker sends Browser forces: Hardware checks for keys
rp.id = "acme.com" clientDataJSON.origin = stored under domain
"https://acme-login..." "attacker-phish.com"
│ │
▼ ▼
Browser checks if "acme.com" NO KEY EXISTS!
matches current domain: (Key was created for
MISMATCH! Browser aborts. acme.com, not attacker)
There are only two possibilities for the attacker, both of which fail mathematically:
Scenario A: Attacker requests rpId: "acme.com"
The attacker's reverse proxy intercepts the challenge from real Acme and forwards it to the victim with rpId: "acme.com".
- The user's browser checks its own URL bar: the origin is
https://acme-login.attacker-phish.com. - The browser checks whether
"acme.com"is a valid suffix of"acme-login.attacker-phish.com". - It is not. The browser instantly terminates the request with a
SecurityError. The hardware authenticator is never even called.
Scenario B: Attacker requests rpId: "attacker-phish.com"
The attacker rewrites the request to use their own domain name so the browser allows the call.
- The browser passes
rpId: "attacker-phish.com"to the Secure Enclave. - The Secure Enclave searches its secure storage for a private key registered to
"attacker-phish.com". None exists! The passkey was generated for"acme.com". The authenticator reports "no credentials found." - Even if the victim mistakenly registered a brand-new passkey on the fake site, the signed
authenticatorDatawould contain SHA-256("attacker-phish.com") andclientDataJSONwould stateorigin: "https://attacker-phish.com". - When the attacker forwards this signed assertion to the real Acme server, Acme checks the signature against its own expected origin (
https://acme.com). The cryptographic hashes do not match. Verification fails.
The signature is mathematically bound to the domain. An authentication token intended for the real website cannot be produced on a fake website, and a token produced on a fake website is mathematically invalid on the real one.
6. Synced Passkeys vs. Hardware-Bound Security Keys
Early FIDO implementations required physical USB security keys (like YubiKeys). If a user dropped their hardware key in the ocean, they were permanently locked out unless they had provisioned a backup key.
To bring phishing-resistant security to billions of everyday users, the FIDO Alliance introduced Multi-Device Passkeys (Synced Passkeys).
Phishing Resistance
Passwords and TOTP OTPs can be intercepted by fake reverse-proxy websites; Passkeys are bound to the browser origin and cannot be phished.
Credential Compromise at Server
Password database leaks expose hashes to cracking; WebAuthn servers store ONLY public keys, which cannot be used to impersonate users.
Credential Reusability
Users reuse passwords across dozens of sites; Passkeys are generated independently per domain, preventing credential stuffing.
Biometric Privacy
Passwords expose user data to the network; Passkey biometric scans NEVER leave the local Secure Enclave hardware.
Friction & Typing
Passwords require manual typing or password manager autofill; Passkeys authenticate with a single biometric touch (Face ID / Touch ID / fingerprint).
+───────────────────────────┬───────────────────────────────────┬──────────────────────────────────+
| Feature | Hardware-Bound Passkey (YubiKey) | Multi-Device Synced Passkey |
+───────────────────────────┼───────────────────────────────────┼──────────────────────────────────+
| Physical Form Factor | External USB/NFC hardware token | iPhone, Mac, Android, PC, 1Pass |
| Private Key Storage | Monolithic silicon crypto-chip | Secure Enclave + Cloud Keychain |
| Exportability | Physically non-extractable | E2E encrypted sync across devices|
| Backup & Recovery | Manual registration of 2+ keys | Automatic via Apple/Google cloud |
| Primary Threat Model | State-sponsored physical theft | Everyday phishing & credential leaks
| Target Audience | High-risk defense, admins, crypto | 5 billion mainstream consumers |
+───────────────────────────┴───────────────────────────────────┴──────────────────────────────────+
How End-to-End Encrypted Cloud Key Sync Works
In a synced passkey ecosystem (such as Apple iCloud Keychain, Google Password Manager, or Bitwarden):
- Local Generation: The private key is generated inside the local device's Secure Enclave.
- Zero-Knowledge Encryption: Before syncing to the cloud, the private key is encrypted with an asymmetric key derived from the user's local device passcode and hardware-fused keys using a threshold secret-sharing protocol (e.g., Apple's CloudKit HSM escrow or Google's secure hardware recovery service).
- Cloud Blindness: The cloud provider stores only encrypted ciphertext. Neither Apple, nor Google, nor a subpoenaed law enforcement agency can decrypt or use the passkeys without the user's physical device hardware and local passcode.
- Seamless Restoration: When the user buys a new phone and signs into their iCloud or Google account, the device undergoes hardware mutual attestation, restores the keychain, and immediately possesses the passkeys.
7. Cross-Device Authentication: The FIDO Hybrid QR Ceremony
What happens when you want to sign in on a desktop computer at work (or a friend's TV) using the passkey stored on your personal iPhone or Android phone?
This is solved by FIDO Cross-Device Authentication (internally known as Hybrid Transport or caBLE - Cloud-assisted Bluetooth Low Energy).
Desktop PC Browser (Chrome) Smartphone (iPhone / Android)
│ │
│ ─── 1. Displays Dynamic QR Code on Screen ──────────────────────────────► │
│ QR contains: [User scans with Camera]
│ • Ephemeral session public key (ECDH) │
│ • WebSocket tunnel URL on FIDO relay server │
│ • BLE pairing secret │
│ │
│ ◄── 2. Bluetooth Low Energy (BLE) Handshake (PROXIMITY PROOF) ─────────── │
│ Validates phone is within ~5 meters of computer screen │
│ │
│ ◄── 3. End-to-End Encrypted WebSockets Tunnel (via FIDO Relay) ────────── │
│ Key agreement: K = ECDH(sk_desktop, pk_phone) │
│ Relay server sees ONLY encrypted noise │
│ │
│ ─── 4. Desktop sends WebAuthn Challenge over tunnel ────────────────────► │
│ [User touches Face ID]
│ [Enclave signs challenge]
│ ◄── 5. Phone returns signed assertion over tunnel ─────────────────────── │
│ │
│ ─── 6. Desktop browser forwards assertion to Relying Party Server ──────► │
Why Bluetooth is Mandatory for Hybrid Logins
Notice Step 2: The phone and computer must perform a Bluetooth Low Energy (BLE) advertisement exchange.
Why couldn't the whole process happen over the internet through the QR code?
If the protocol worked over the internet without proximity verification, an attacker in another country could stream a fake login page over Zoom or Discord, display the QR code, and trick the victim into scanning it. The victim would tap Face ID on their phone, accidentally authenticating the remote attacker onto the service!
Because Bluetooth radio waves physically attenuate within 5 to 10 meters, requiring an ephemeral BLE advertisement exchange proves that the phone and the desktop computer are located in the same physical room. A remote attacker on the other side of the planet cannot complete the Bluetooth handshake, mathematically eliminating remote QR phishing attacks.
8. Summary: The Cryptographic Triumph of Passkeys
The transition from passwords to passkeys represents the most fundamental security architecture upgrade in the history of the World Wide Web:
- Elimination of Shared Secrets: Passwords require both client and server to know a secret. Passkeys use asymmetric cryptography: the server holds only a public key, eliminating server-side credential theft.
- Deterministic Origin Binding: The browser, not the user, injects the exact website origin (
https://domain.com) into the signed payload. Phishing sites cannot forge this origin. - Hardware-Isolated Private Keys: Private keys are generated and sealed inside tamper-resistant hardware security chips (Secure Enclave, TPM), where they can never be extracted by malware.
- Biometrics Stay Local: Biometric verification (Touch ID, Face ID) serves only to unlock the local hardware chip. Biometric data is never digitized into a token and never sent across a network.
- Zero-Knowledge Synchronization: Multi-device passkeys combine hardware isolation with end-to-end encrypted cloud synchronization, solving account recovery without weakening cryptographic strength.
- Proximity-Enforced Cross-Device Flow: Hybrid authentication uses Bluetooth Low Energy as a physical proximity circuit breaker, preventing remote attackers from exploiting cross-device login ceremonies.
Where to Go From Here
Follow downstream mechanisms, contrasting architectures, or applications of these principles.
How Single Sign-On (SSO), OAuth 2.0, and OpenID Connect Work
How does 'Sign in with Google' or corporate SSO let you access third-party websites without ever revealing your actual password to those sites?
Why SMS OTPs Sometimes Arrive Late or Fail Entirely
Deep-dive following foundational explainer Why SMS OTPs Sometimes Arrive Late or Fail Entirely
How PageRank and Link Analysis Rank the Web
More in Computing & Digital Architecture
How Binary and Logic Gates Became Computation
More in computing
Verified Specifications & Architectural References
This explainer is grounded in primary-source engineering specifications, regulatory circulars, and standard documentation.