Do keys allow user identification?

I am the proud (?) owner of Nitrokey 3.

During the registration process on Github I came across the following text:

"If your security key is capable of verifying your identity (for example, Touch ID, Windows Hello, Android thumbprints, or PIN-locked or biometric hardware keys), then it’s eligible to be upgraded. The next time you sign in with that security key, we’ll ask you if you want to upgrade it to a passkey, which will re-register it with your passkey provider. This re-registration ensures that your passkey is discoverable during authentication, and synced, if supported. Because passkeys are privacy preserving, you might have to trigger your passkey a few times during that upgrade flow so we can make sure we’re upgrading the right credential Once you do, you’re all set. “for a passwordless experience.”

I’m curious about the phrase “which will re-register it with your passkey provider”? Does this mean Nitrokey collects my data (name, address, bank account number) and compares it with all the physical keys I’ve purchased? Does Nitrokey provide this information to identify me on websites?

Let’s say I’m registered on website 1 under the username “Tom Smith.” On website 2, I’m registered under the username “Ldskgjpd.” I used the same Nitrokey for registration, but different email addresses.

Situation 1) All data from both websites has been leaked. Is it possible to determine if “Tom Smith” and “Ldskgjpd” are the same person?

Situation 2) The same person works as an administrator for two companies and has full access to all data on both websites, including technical information. Can he find out that “Tom Smith” and “Ldskgjpd” are the same person?

I’ll try to answer this myself, since I think I’ve figured it out a bit.

When logging in to a website, a request is made to generate a temporary password corresponding to the unique ID of the physical key. During this request, the website sends a site-identifying string of characters (for example, “github.com”), the value of which is mixed with the unique device ID when generating the temporary password. This way, different temporary passwords are generated for each website, and the administrator of both websites won’t be able to tell that the same user is registered on different websites (unless, of course, the websites send different site-identifying strings of characters).

BUT!!! This works only if the website doesn’t request a key certificate during registration. This certificate uniquely identifies the physical key and allows for user identification!!!

Not all websites request a certificate, and this can be verified. ChatGPT wrote a script for me that allows you to determine whether a website requests a certificate or not. Based on my superficial knowledge of JavaScript, the script is safe, does no harm, and doesn’t send anything anywhere.

Using the script is quite unusual for me: create a bookmark in the browser with any name and paste the script code under the URL. When registering a new key, open the console (F12) and click on the bookmark (having a new key isn’t required). Then click “Add a new key” and check the console to see whether the site has requested a certificate.

Script:

javascript:(function(){ function color(text,color){console.log(“%c”+text,“color:”+color+“;font-weight:bold”);} function installInterceptor(){ if(navigator.credentials.__patchedWebAuthn) return; const origCreate=navigator.credentials.create; const origGet=navigator.credentials.get; navigator.credentials.create=async function(opts){ console.group(“:new_button: WebAuthn REGISTER (navigator.credentials.create)”); if(opts && opts.publicKey){ const pk=opts.publicKey; color("RP ID: "+(pk.rp?.id || “(not specified)”),“dodgerblue”); const att=pk.attestation ?? “(not specified — means none by default)”; if(att===“direct”) color(“:warning:%EF%B8%8F attestation: “+att+” (requests a device certificate!)”,“red”); else if(att===“none”) color(“:white_check_mark: attestation: “+att+” (private, no certificate)”,“green”); else color(“:information_source:%EF%B8%8F attestation: “+att,“orange”); if(pk.user) console.log(“user.id:”, pk.user.id ? new TextDecoder().decode(pk.user.id) : “(binary id)”); if(pk.challenge) console.log(“challenge:”, pk.challenge); } else { color(“:warning:%EF%B8%8F Called without publicKey”,“gray”); } console.groupEnd(); return origCreate.apply(this,arguments); }; navigator.credentials.get=async function(opts){ console.group(”%F0%9F%94%90 WebAuthn LOGIN (navigator.credentials.get)”); if(opts && opts.publicKey){ const pk=opts.publicKey; color("RP ID: "+(pk.rpId || “(not specified)”),“dodgerblue”); if(pk.allowCredentials?.length) console.log(“allowCredentials:”, pk.allowCredentials); color(“:information_source:%EF%B8%8F Certification is not used during login (only during registration)”,“gray”); } else { color(“:warning:%EF%B8%8F Called without publicKey”,“gray”); } console.groupEnd(); return origGet.apply(this,arguments); }; navigator.credentials.__patchedWebAuthn=true; color(“:white_check_mark: WebAuthn Inspector is active — open console (F12 → Console)”,“green”); } installInterceptor(); setInterval(installInterceptor,2000);})();

What should I do if a site requests a certificate? Some browsers can intercept the key certificate and modify it (Firefox), but this isn’t certain, and I’ll ask for public opinion in another thread.