How secure each generated private key by a FIDO2 authenticator is stored?


I am trying to understand how FIDO2 CTAP2 protocol works reading different manuals like:

Actually I am even not sure is it description of U2F CTAP1 or FIDO2 CTAP2 protocol.

According to mentioned documentation an authenticator creates a key pair:

Authenticator Creates New Key Pair and Attestation - Before doing anything, the authenticator will typically ask for some form of user verification. This could be entering a PIN, using a fingerprint, doing an iris scan, etc. to prove that the user is present and consenting to the registration. After the user verification, the authenticator will create a new asymmetric key pair and safely store the private key for future reference. The public key will become part of the attestation, which the authenticator will sign over with a private key that was burned into the authenticator during its manufacturing process and that has a certificate chain that can be validated back to a root of trust.

After reading above paragraph from the documentation a hardware token looks for me like a small user’s own local “certificate authority” with a secure private key inside the hardware token used for a signature and attestation of a newly generated key pair. It looks like creating a signed certificate, is not it?

Please explain, private key of the newly generated pair is stored on user’s the disk file system? and in which format? Is it just a raw plaintext private key material or is it somehow encrypted and by which another key?

For example if we look at how the latest version of OpenSSH works with U2F tokens we can see that
ssh-keygen -t ecdsa-sk generates a new key pair somehow related also to another third key - private key inside a hardware token.

Lets after executing ssh-keygen we get in result two files: id_ecdsa_sk and

What exactly is inside a id_ecdsa_sk ? Is it just a raw private key material used in OpenSSH like any other keys stored on the disks? If it is stolen then we loose a protection from a MITM or only if also a hardware key is stolen? How is it provided/implemented in simple words without reading sources of OpenSSH?

According to:

The private key file
should be useless to an attacker who does not have access to the
physical token.

What about MITM, how is it achieved?

I know OpenSSH for now uses only U2F/CTAP1 protocol yet.

In CTAP2 protocol a keypair is generated the same way too? Is it being stored more secure or the same way as in CTAP1 protocol too?

Well, according to:

You’ll get a public/private keypair back as usual, except in this case,
the private key file does not contain a highly-sensitive private key but
instead holds a “key handle” that is used by the security key to derive
the real private key at signing time.

So, stealing a copy of the private key file without also stealing your
security key (or access to it) should not give the attacker anything.

If I understand correctly id_ecdsa_sk is a so called key handle.
Then U2F device can evaluate after signing (derive?) a real SSH private key from such a key handle using its own preflashed U2F master private key.

But does U2F device return a real derived SSH private key to the host PC in just a pure plain text via USB channel?
So can a real derived SSH private key be intercepted by an emanation scanner?
If it is true then using a PKCS11 device like a Nitrokey PRO2 looks more secure for SSH authentication at least because a true user’s own SSH private key (not a master key used to derive a key from a handle) is always kept secret in a cryptochip and the only some session specific derived info becomes available to an attacker? So PKCS11 like devices are better even if a PKCS11 session lacks an USB channel encryption?

Most likely it works the same way for decrypting LUKS2 passwords in programs like fido2luks, etc.? Can a derived LUKS2 password be intercepted on the USB channel from a U2F key? Is it the same for FIDO2 authenticator? If USB channel of U2F/FIDO2 is not encrypted as whole, may be at least some of it’s fragments are still encrypted?

Can anyone knowledgeable and familiar with internals of llibfido2 and FIDO2 specifications comment regarding to this question?


Final private key never leaves the Nitrokey FIDO2 device, but only the signature is returned. For OpenSSH the symmetric key is established for the further communication like in usual case.
In the FIDO2 protocol only the PIN is foreseen to be sent encrypted according to the CTAP2 specification.
FIDO2/CTAP2 generates the signatures in the same way as predecessor, with some extensions.

Lets there are two private keys:

  1. FIDO2_private_key inside a FIDO2 token flashed by your manufacturer. Sure this key never leaves a FIDO2 hardware token, I do not argue for an opposite. Btw, can FIDO2_private_key be reset for example to a random new one if needed?

  2. SSH_private_key - is a true original raw asymmetric key material for an OpenSSH key pair. Earlier without U2F token it would be saved in a file like id_ecdsa in the file system directly, may be encrypted by a password if specified to encrypt.
    key_handle - is a contents of the id_ecdsa_sk file, where SSH_private_key is NOT stored as earlier. It is just an argument for for U2F signature function now to somehow calculate the actual FIDO2_private_key.

According to the above OpenSSH manuals/discussion:

You’ll get a public/private keypair back as usual, except in this case,
the private key file does not contain a highly-sensitive private key but
instead holds a “key handle” that is used by the security key to derive
the real private key at signing time.

If I understand correctly SSH_private_key=derive_function(signature_algo_function(FIDO2_private_key, key_handle))
Where signature_algo_function is a function to “derive” one key from another. Please let me know where can I read a simple explanation about how raw SSH_private_key is derived from FIDO2_private_key?

And very important issue for me is that nobody else sniffing a USB channel could derive the same raw SSH_private_key too.
But how is it possible to protect SSH_private_key if signature is passed through as USB channel in a plain text? Can an earlier intercepted from USB already generated signature (even without a FIDO2 hardware token) be used later by an attacker to derive SSH_private_key by himself once again the same way as it is done on my side if an attacker has a key handle (id_ecdsa_sk file) too? How can I somehow prevent this?

I try to describe you an attack when both result from signature_algo_function and its argument key_handle becomes known to the attacker, does OpenSSH derive algo protects us somehow in such situation?
Attacker does not need a token hardware anymore to calculate SSH_private_key=derive_function() if he knows already a correct result for signature_algo_function and the key_handle too.

This is OpenSSH specific, not required for implementation on the firmware. You need to look into their documentation.

Exactly. From the description you have linked this is the whole process, and it works at rest. In case the host PC is compromised you can get the key as well, but keep in mind this is harder than just coping the usual .ssh/* files, and this is the advantage. In this case keeping the key on the smart card and using it for the cryptographic computations is more secure, but using FIDO2 for SSH login is still better than keeping all key data on host.

If your host PC is compromised then nothing really could help, maybe except direct / secure communication with the assumption that you can believe what you see on the screen, which is unlikely.

I was just trying to understand if a U2F or FIDO2 token can save me from a remote contact less emanation attack using special radio scanners. Now it looks like a U2F/FIDO token cannot protect me from a party scanning USB emanation remotely?

Do you have any security analysis results of the data exchange protection protocol used in your Nitrokey HSM2 product?

For example for a JavaCard SCP02 and SCP03 there are research results:

Cryptanalysis of GlobalPlatform Secure Channel Protocols

If you are worried about EM emissions, how about using a proper Faraday cage for that?
Looking from this side, the power fluctuations are even more curious side-channel attack to counter.

Regarding HSM, please create separate topic.

If a battery powered notebook is used detached from AC power line then can it still be watched for power fluctuations remotely? What about wired network cable like an Ethernet? What if using an optical network cable to connect to the Internet and first eth->mod convertor device is powered from a battery too?