A new login technique is becoming available in 2023: the passkey. The passkey promises to solve phishing and prevent password reuse. But lots of smart and security-oriented folks are confused about what exactly a passkey is. There’s a good reason for that. A passkey is in some sense one of two (or three) different things, depending on how it’s stored.
Someone on slashdot correctly pointed out that these are only single factor on the server end. You enter a pin to unlock the device, the server can check if the device says you unlocked it, but there is no sending a second factor to the server. If a device was hacked to get the keys, or just says to the server that you presented a pin but didn’t really, the server has no clue. Passkey + TOTP would be multi factor on the server side.
TOTP generated on the same device as the passkey is not a secondary factor. It will have been compromised together with the passkey.
For passkeys, the secondary factors are used to access the passkey vault, not auth to the server. And these secondary factors should be a master password, biometrics, or physical keys. TOTP and SMS are out.
I understand how it works, but again, it is not two factors being used to authenticate to the server.
It is a single factor being used to access the vault. The server has no way of confirming this actually happened, the device just tells the server it has happened. A single factor is then used for authentication. This seems especially worth knowing since most cell phones deliberately weaken the security by sharing them between devices.
Passkeys would preferably not be stored on the same device as a secondary factor used for authentication. Hardware tokens have supported them for years at this point, they can also hold TOTP keys instead.
I’m not sure I follow you - if someone can compromise the key material on my phone that is protected by a different factor, then it doesn’t matter whether the 2FA is server-side or not, it’s compromised either way.
If they compromise key material on your phone they still cannot get into whatever you are authenticating to, because it uses a completely separate factor that should not be on your phone.
It seems like you are trying to protect against a compromise of the user’s device. But if their device is compromised then their session is compromised after auth anyway and you aren’t solving much with extra auth factors.
You’re assuming that the passkey is on their phone and the phone is compromised. Passkeys can also be stored in password managers, or hardware tokens, or people’s iCloud or Google accounts. And if someone’s device is compromised, they have keys to everything even if the user never logs into those services to grab session data. If someone compromises my password vault they get passwords, but not TOTP keys. If they compromise my vault that is holding passkeys, that is all they need.
I am only pointing out that a single factor is all that is sent to the sever, with most no longer allowing a secondary factor for authentication, and all of the security is all dependent on the client-side now.
If the user can perform all steps on the same device then it doesn’t make sense to assume only specific set of keys will be disclosed, you have to assume everything on the device can be compromised
Passkeys are indeed only the first factor. A second factor could be a(n unrelated) password, or raw biometric data.
The traditional authentication factors (something you know, something you have, something you are) still work like they used to. Passkeys use the “something you have” factor by default.
The “something you are” factor (biometrics) isn’t commonly used, because most services actually use a stored secret that gets unlocked through biometric rather than biometrics data directly; any fingerprint login is just a public/private key in implementation, except the hardware is supposed to not use that key unless the biometrics sensor validates you.
Theoretically you could achieve the same factor as passkeys by logging in through username + TOTP code, because TOTP codes are only supposed to be generated on a dedicated device you have.
With some implementations of passkeys, the factor becomes a bit ambiguous. For example, a synchronised passkey behind just a password might as well be a password, albeit for a different service.
For traditional passkey storage (a TPM, a Yubikey), this isn’t a problem of course.
The second factor doesn’t necessarily exist, since you’ve moved all of that to the client side now. It entirely depends on implementation and that the implementation is done correctly and is honest. The server only knows that you have the key, it’s single factor authentication.
In the past, it verifies that I know the password and that I have a key on the server side through separate challenges.
It’s still way better than username / password, it just has new (more difficult) vulnerabilities.
This is where PAKE algorithms for secure password checks fits in
https://slrpnk.net/comment/3782237
Passkey plus TOTP doesn’t really make sense (they’re both client side cryptographic keys, you don’t need two protocols), at least use a PAKE algorithm with a PIN instead if you want the server to be able to check the user’s knowledge of a secret without sending it in a readable form