DEV Community

Cover image for How Passkeys Work: Why a Perfect Phishing Page Gets Nothing (Plus Lost Phones and the "Trap" Debate)
RuntimeStack
RuntimeStack

Posted on AI-assisted

How Passkeys Work: Why a Perfect Phishing Page Gets Nothing (Plus Lost Phones and the "Trap" Debate)

This login page is fake... and it's perfect. Your password would walk right in.

So how do you log in, when the site never gets a secret?

A pixel-identical fake login page at runtimebank-secure.com: the typed password goes to the attacker, and the passkey button is crossed out

One analogy makes it click: a signet ring.

What passkeys replace

First, what passkeys replace: the password. Whoever has your password logs in as you, from anywhere.

The ring and the impression

Picture a signet ring and its wax impression. A passkey works the same way, with a pair of keys.

Passkey Signet ring
private key the ring: it stays on your devices, never with the site
public key the impression: that's all the site stores
signature the stamp
challenge a blank card with a random number
site address (RP ID) the engraving on the ring

Where the analogy breaks: a real ring can be copied from wax.

A pair of keys: the private key (the ring) stays on your device, the public key (the impression) goes to the website, and the stamp matches

Creating a passkey

The site gets the impression, the public key, and that's ALL it stores.

So if that server gets breached, the attacker gets a pile of impressions.

But if the site never gets anything secret... how does it know it's really you?

Signing in

The site sends a challenge: a blank card with a random number it's never sent before.

Your device stamps it with the ring. That stamp is the signature.

The site checks the stamp against the impression on file. Match? You're in.

runtimebank.com  --  blank card: 8f3a…c91  -->  your phone
runtimebank.com  <--  signature (the stamp)  --  your phone
checked against the public key  ->  you're in
secrets sent: 0
Enter fullscreen mode Exit fullscreen mode

Sign-in sequence: the site sends a challenge, the phone signs it with the private key, the site checks it against the public key, zero secrets sent

Why the fake page gets nothing

Every ring is engraved with the site it was made for: runtimebank.com.

And your browser, not the ring, checks the real address before it brings one out.

The fake site is runtimebank-secure.com. One word off, so no ring matches... so there's nothing to offer. Your passkey can't be phished.

And even if a stamp somehow got made there, the browser writes the address onto the card first... so it carries the fake address, and the real site rejects it.

origin:   runtimebank-secure.com
rings:    runtimebank.com ≠   shop.com ≠   mail.com ≠
passkey secrets sent: 0
Enter fullscreen mode Exit fullscreen mode

The browser, the clerk, checks the origin runtimebank-secure.com against the ring engravings; none match, so the passkey can't be phished

Who shows the popup?

So your browser picks the ring. But who's holding them, and who's showing you that popup?

That popup is your browser or phone, not the website.

The website asks your browser, and your browser asks your passkey provider. That's whatever holds your rings: iCloud Keychain, Google Password Manager, 1Password, Bitwarden, or a hardware key.

Signing in on a laptop with your phone? You scan a QR code, and Bluetooth checks it's nearby.

Website asks the browser or phone, which shows the passkey popup and asks the passkey provider; a laptop signs in with a phone by QR code and Bluetooth

Lost phone: synced vs device-bound

But here's the catch with a ring that lives on one phone. Lose the phone, lose the ring.

So passkeys made on a phone or in a password manager are usually synced. Your provider copies them, end-to-end encrypted, to your other devices.

Phone gone? Sign in to your provider on a new one, and your rings come back.

That makes your provider account the master key, so protect it well.

A hardware key is device-bound, with no copies. So register two... and keep one in a drawer.

![Lost phone: the provider restores end-to-end encrypted passkeys to a new phone; the provider account is the master key; a hardware key is device-bound]

Face, fingerprint, PIN

Your face or PIN unlocks the ring box, right there on the device.

Your fingerprint and face never leave the phone, and the site never sees them.

Stolen phone

A leaked password works for anyone, from anywhere, without ever touching your phone. So the phone itself is what to protect.

Here's what to actually do: a long passcode, not four digits, and remote lock and wipe turned on.

The password fallback

One more honest catch... most sites still keep a password or an email reset as a backup.

That's a spare key under the mat, and attackers always check the mat.

So if a site where you use a passkey suddenly asks for your password... stop. Assume it's the fake page, and type the address yourself.

And if a site lets you remove the password, do it.

Lock-in

And switching providers? The FIDO Alliance, the group behind passkeys, is rolling out Credential Exchange. It's a standard way to move passkeys between managers, encrypted.

Are passkeys a trap?

The viral argument is about one optional feature, attestation.

A site can ask for proof of what made your passkey, signed by the maker.

Now the fact check. Synced passkeys from Apple, Google, 1Password and Bitwarden send no signed proof at all.

So it's worth watching... but a consumer site that required it today would lock out almost everyone.

Recap

Your private key is the ring. It stays on your devices, never with the site.

The public key is the impression. That's all the site stores.

The honest part: lock your phone down, and never type a password where your passkey should be.

That fake page? Your password would've walked right in. Your passkey never even showed up.

What's still stopping you from turning passkeys on? Tell me in the comments.

More in this series: JOSE and JWT, PKCE, Device Flow.


This is the written version of a 7-minute animated explainer on RuntimeStack. Sources: passkeys.dev: What are passkeys?, passkeys.dev: Terminology, W3C Web Authentication Level 3, FIDO Alliance: Passkeys, FIDO Alliance: Credential Exchange specifications, "Passkeys are a trap" (nonfunctional), Scott Helme: "Passkeys are not a trap".

Top comments (0)