Hacker News new | ask | show | jobs
by t0astbread 1955 days ago
As someone who's not familiar with U2F or comparable standards I have a general question about the topic: When registering a key for multiple accounts (at the same site or at different sites) can website owners link those accounts by some common "key ID"? In the sense of: "Oh, this is Bob's key so this account must belong to Bob".
4 comments

No, they cannot. This is an explicit design goal of FIDO (https://fidoalliance.org/specs/fido-security-requirements/fi...).

The actual public key used for logging in to a specific site is completely random.

Optionally, the website can ask for "attestation", which is intended to prove that the public key is from a specific vendor/model. To make this also unlinkable, devices are supposed to share attestation keys in batches of 100k units.

Ah, I see! So cross-site (across multiple relying parties) linking is prevented but if I have multiple accounts within one relying party they can be linked?
FIDO (except in resident mode which we'll ignore here) requires the site requesting you authenticate to hand over a large opaque blob called an ID that your authenticator gave it when you enrolled the authenticator. This ID will be different for every time you enrolled an authenticator, and it can recognise its own IDs (using modern cryptography). To prevent you enrolling the same one twice, sites hand over a list of the ones you already enrolled and your authenticators say "I'm already enrolled here" if they recognise the ID.

So somesite.example if it suspects Jim and Candy are the same person, or at least, using the same FIDO authenticator, could do this:

When Jim signs in, they present Candy's ID. If they're right, Jim's authenticator goes "Oh I recognise this, signed". If they're wrong, Jim gets an error. Weird. Presumably on a second try they give Jim's ID and it works so that Jim isn't too suspicious.

So this attack would allow a site that strongly suspects you're doing this to prove it, to their own satisfaction anyway. But it doesn't offer any practical way for a site with more than a handful of users to just match all the users.

In resident mode, you have to admit who you are as part of signing in - you're not separately typing in an email address or username or whatever, you just press the button on your authenticator (or touch the sensor on your phone, or whatever) and you're in. This obviously means it doesn't make sense for Jim and Candy to use one device for two users on the site, and most likely their device will prohibit them from trying to enroll the second user this way.

Edited to add: If someothersite.example plays Jim or Candy's IDs from somesite.example (may it's secretly run by the same people, or they stole a database backup) to Jim (or Candy) they don't work, the IDs are bound to the domain, so these don't match.

I implemented this mode in a Django library [0] (demo on www.pastery.net) because I love the idea of not needing a password manager any more, just simply having a key with you to log in anywhere, but it doesn't seem to have widespread browser support yet.

Maybe I made a mistake, but Firefox doesn't seem to work very reliably with it, and mobile support is spotty too.

[0] https://pypi.org/project/django-webauthin/

Yes, resident credential (aka "Client discoverable") support in (at least) desktop Firefox is broken and has been for a long time. I believe it's also absent (but at least not broken) in desktop Chrome. :/
Public key and key handle would still be unique and unlinkable for each account on the same site with the same u2f token. The yubico documentation is pretty good at explaining this https://developers.yubico.com/U2F/Protocol_details/Overview....
I think he's asking about have two accounts on the same website.

I'm not so sure they cannot associate.

There's no way to do this _discreetly_ if the key is properly implemented.

When you register your key on a service, the service sends an application identifier down. Your key then creates a fresh key pair and sends a handle (name for that keypair) and the public key back to the service. Later when you authenticate, the service sends down the handle and challenge. Your key uses the handle to find the right private key and sign the challenge, which is checked by the service using the public key to confirm that you do indeed possess the private key.

Since fresh keypairs (and handles) are generated each time you register a key, the service can't use the registration process to identify whether you're re-using a physical key (it should look no different from using a new physical key).

Alternatively, a service can check if your physical key contains other handles by initiating requests with them, but this will almost always be very obvious. E.g. If they suspect you are Bob, they could request a challenge with _Bob's_ handle.

But they can't just spray handles, since if they do this when you're not expecting to authenticate anything, it will be quite obvious: your key, and any intermediate applications like the browser or OS, will behave like they are authenticating. With a well implemented key, you will be safe as long as you don't touch the key on spurious authentication attempts. The service won't be able to tell whether the key doesn't have the handle (and is ignoring the challenge) or if the key does have it but you just didn't touch the key because you weren't expecting an authentication request.

This leaves the service with the final option of only doing the test while you're trying to log into what they suspect is an alternate account. That means they can only do one check and will have to be fairly certain about you being Bob lest you be tipped off. If they guess right, you won't be able to tell a difference but the service will know that you can authenticate with Bob's handle while trying to log in as Alice. If they guess wrong however, you might become suspicious since the authentication will fail and in a non-standard way (e.g. the key can indicate that it has received a foreign handle).

All this means is that, if the service is trying to tie identities to "serve ads", they won't have a feasible way to do this with U2F. But, if it's a threat actor with nation state level resources and lots of time then... well... nothing consumer level will really help you (though U2F still puts up a decent fight).

For U2F I don't believe that's the case for most devices.

Yubikey outlines their method here[1]. They generate a different keypair for each website public key and have the server store an encrypted and authenticated copy of the private key using a single on-device key. So baring breaking the underlying primitives the server will only have a site-specific public key and a site-specific encrypted blob.

[1]: https://developers.yubico.com/U2F/Protocol_details/Key_gener...

They are asking about two user accounts on the same site, not with two websites on the same server. As in two GMail accounts.
I think that would be the public key. You can roughly think of it as the hardware key has a private key embedded in it in a way that it (supposedly) can't be gotten off. That private key has a corresponding public key. You can think of the private key as the password and the public key as the username. So I think the public key is the "key ID" you're looking for.
This is not how U2F works. The sites never see the device's long-term public key.