U2F/Fido2 based SSH keys on Windows

When trying to figure out why ssh-agent forwarding wasn't working from Windows to an Ubuntu 22 server, I saw that build V8.9.0.0p1-Beta of Microsoft's OpenSSH port included U2F/Fido2 hardware authenticators.


There's a few ways to install this, I'll use winget (should already be available in Windows 10/11).

From a regular powershell prompt:

winget install Microsoft.OpenSSH

This will automatically restart the Microsoft ssh-agent using the new version in C:\Program Files\OpenSSH:

Get-Service ssh-agent

Creating a SSH Key

I'll create a key using my YubiKey 4 and put it into the .ssh\yubikey4 file. I'll set the ssh key comment to "yubikey 4" as a reminder to myself which hardware this key goes with. Be sure to use the newer OpenSSH in C:\Program Files\OpenSSH rather than the older system one in C:\Windows\System32\OpenSSH

& "C:\Program Files\OpenSSH\ssh-keygen" -t ecdsa-sk -C "yubikey 4" -f yubikey4

This pops up some dialog boxes:

Security Key Setup
ssh can see your security key properties
Touch your security key's user presence button
optional passphrase

The ssh key itself is stored on the yubikey, the "private key" file just contains some related metadata (See the PROTOCOL.u2f file at the bottom of this page for details). You need both the hardware key and the file data in order to use this. You can make multiple ssh keys with the same hardware key, each will be unique.


I setup npiperelay to connect WSL2's ssh to Microsoft's ssh-agent. After building it with Windows go, I put npiperelay.exe in my ~/.ssh/ directory.

export SSH_AUTH_SOCK=~/.ssh/agent.socket
if ! fuser -s $SSH_AUTH_SOCK 2>/dev/null; then
  rm -f $SSH_AUTH_SOCK
  setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork,umask=077 EXEC:"$HOME/.ssh/npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork

Trying to generate a new ssh key using WSL2 fails because it tries to talk directly to the hardware (which is not available in the WSL2 VM):

ssh-keygen with U2F/Fido2 keys in wsl2 fails

But listing the key works:

ssh-add -l

As well as using it to login:

ssh -v server

ssh pops up a confirmation dialog when I use this key:

user presence button dialog

This needs OpenSSH 8.2 or higher on both the client and the server, so it doesn't work for Rocky Linux 7 (OpenSSH 7.4p1) or 8 (OpenSSH 8.0p1).


Trying to add the U2F/Fido2 key from WSL2 ssh-add or from KeePassXC fails. Windows OpenSSH has their own SSH agent code in order to integrate with the Windows systems. I opened a bug report with the details and then a PR to fix this issue, which is now merged and should hopefully be in the next release.

More info: