One-Time Codes vs. Passkeys: What "Phishing-Resistant" Actually Means
Not all multi-factor authentication is equal. Here is the mechanical reason a security key or passkey stops phishing that a six-digit code can't.
"We have MFA" is treated as a finish line. But there's a real, mechanical difference between the common kinds, and it decides whether a determined phisher gets in. The difference is whether the second factor is bound to the site you're talking to.
How a one-time code works
A one-time code — the six digits from an authenticator app (TOTP) or an SMS — is a shared secret played out over time. Your app and the server agree on a seed; both run the same function over the current time to produce the same short-lived number. You read it off your screen and type it into the login form. The server runs the same calculation and checks it matches.
Notice what the code is and isn't. It proves you currently possess the seed. It does not know, or care, which website you typed it into. It's just a number, and a number can be typed anywhere.
How phishing defeats it
This is the whole vulnerability. A phishing page that looks like your real login asks for your password and then asks for your code. You read the valid code off your authenticator and type it into the fake page. The attacker's server, sitting in the middle, immediately relays your password and your still-valid code to the real site and logs in as you. Push-approval MFA has the same flaw in a different costume: a prompt pops up, a login really is happening, so you approve it — for the attacker.
The code was perfect. You were cooperative. The only thing wrong was the destination, and nothing about a one-time code checks the destination.
How a passkey (FIDO2/WebAuthn) is different
A passkey, or a FIDO2 hardware security key, changes the mechanism entirely. Instead of a shared number, it uses public-key cryptography: a private key that never leaves your device, and a matching public key the site stored when you registered. To log in, the site sends a challenge; your device signs it with the private key; the site verifies the signature with the public key.
The decisive detail is that the signature is bound to the origin — the actual domain making the request — as part of the protocol. Your device will only produce a valid assertion for the real site it was registered to. Land on a lookalike domain and the key simply will not generate a usable signature, because the origin doesn't match. There is no code to read aloud, no prompt to approve, nothing to relay. The thing being phished doesn't exist.
Why "phishing-resistant" is the right phrase
That's what people mean by phishing-resistant MFA: the factor is cryptographically tied to the legitimate site, so it can't be tricked into authenticating against a fake one. It also can't be replayed, because each challenge is unique, and the private key can't be copied off the device.
One-time codes still beat passwords alone — they stop credential-stuffing and casual reuse. But against someone who can stand up a convincing fake login and relay in real time, codes and push prompts fail and passkeys don't, for a reason that has nothing to do with user training and everything to do with what's bound to what.
The takeaway
A one-time code proves you have a secret; a passkey proves you're talking to the real site. The first can be handed to the wrong destination by a cooperative human; the second can't, by construction. When the goal is surviving a determined phisher — start with the people who can reach the most — that distinction is the entire game.