Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save daemonhorn/a6af1b76457b2c10b8058d0a2c919bc3 to your computer and use it in GitHub Desktop.
Save daemonhorn/a6af1b76457b2c10b8058d0a2c919bc3 to your computer and use it in GitHub Desktop.
Setting up Yubikey/Solokey(v2)/Windows Hello for OpenSSH via PIV or FIDO authentication on Windows

Overview

This guide covers using both PIV smartcard and FIDO2 features of your Yubikey, SoloKey(v2), and Windows Hello for SSH authentication in a secure and portable manner. FIDO2 support works with YubiKey, SoloKey(v2), and Windows Hello(biometric:face, biometric:fingerprint, secure-element/pin) with OpenSSH as a relatively new feature which requires updated client and server versions. PIV support has been around with PKCS#11 for many years in the OpenSSH codebase, and is considered a more stable and ubiquitous solution when an applicable PKCS#11 library is available for your platform.

Windows Yubikey for ssh via PIV

Example below assumes that you have a piv key already generated in a yubikey slot the way you want. If you need to generate a new one, read the excellent documentation here: https://developers.yubico.com/PIV/Guides/SSH_with_PIV_and_PKCS11.html and https://support.yubico.com/hc/en-us/articles/360021606180-Using-YubiKey-PIV-with-Windows-native-SSH-client

  • This explains basic configuration of setting up a yubikey for ssh via PIV authentication on Windows.
  1. Install Windows OpenSSH client version 8.9p1+ To use with Win10/Win11 openssh-portable, you must have a version that supports pkcs11 loading on Windows (8.0+) check your version with ssh -V
  • Latest as of May 2024 is: OpenSSH_for_Windows_9.5p1, LibreSSL 3.8.2
  • If you want ssh-agent pkcs11 support, requires openssh for windows version 8.9p1+
  • You can download from here: https://github.com/PowerShell/Win32-OpenSSH/releases
  • Latest Win10/Win11 can alternatively use winget support to install: winget search openssh winget install Microsoft.OpenSSH.Beta
  1. PKCS11 DLL Support for Yubikey on Windows
  • You need to install the latest yubico-piv-tools package for Windows to get the correct libykcs11.dll for full support from https://developers.yubico.com/yubico-piv-tool/Releases
  • Using winget: winget install Yubico.Piv-Tool
  • Under powershell, or choose your favorite method of downloading yubico-piv-tool (example is v2.5.2 x64): Invoke-WebRequest https://developers.yubico.com/yubico-piv-tool/Releases/yubico-piv-tool-2.5.2-win64.msi -OutFile yubico-piv-tool-win64.msi
    • Run the installer .\yubico-piv-tool-win64.msi
  1. Configure Windows system environment variables
  • Some reference documentation on setup here: https://developers.yubico.com/yubico-piv-tool/YKCS11/
  • If you forget this step, the libykcs11.dll will not load properly for ssh-add/ssh-agent and possibly ssh.
  • Modify your Windows Path environment variable (global for system, not user) to include both: C:\Program Files\OpenSSH C:\Program Files\Yubico\Yubico PIV Tool\bin
  • Settings->Find->Edit the System Environment Variables->Environment Variables[BUTTON]->System variables(bottom)->Path->Edit[BUTTON]
  • Restart powershell/cmd after changing environment variables to ensure changes take effect.
  1. Test out connectivity using Windows ssh and PIV via pkcs#11
  • Using example below, give it a test in verbose mode (change user@host to a real host you have ssh access to) ssh -v -I "C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll" user@host
  1. Configure current user ssh config for pkcs11 library
  • cmd.exe version: echo PKCS11Provider "C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll" >>%USERPROFILE%/.ssh/config
  • Powershell version: Add-Content -Path $env:USERPROFILE\.ssh\config -Value 'PKCS11Provider "C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll"'
  1. (optional) use with ssh-add and/or ssh-agent (will prompt for pin aka passphrase) ssh-add -s "C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll"
  • If this fails with "agent refused operation" after entering your PIN, Check your Event Viewer logs (under Application and Services Logs->OpenSSH->Admin) for detailed error messages.
  • Make sure you have the C:\Program Files\Yubico PIV Tool\bin\ path listed in the SYSTEM environment variable for %Path% (not the user environment variable, as ssh-agent runs in a different environment context to your normal user.
  • You can also try restart-service ssh-agent (if it is dead or not running for some reason)
  • Check privs with `sc.exe qprivs ssh-agent1 (should result in 5 privs ending in SeImpersonatePrivilege). There was a bug with earlier versions of the ssh-agent windows service installer privileges. (Fixed in OpenSSH v8.9.1p1)
  1. Export public keys for use with ~/.ssh/authorized_keys files on remote hosts for users ssh-add -L or ssh-keygen -D 'C:\Program Files\Yubico\Yubico PIV Tool\bin\libykcs11.dll'

Windows ssh with FIDO2 support on Yubikey

Starting with OpenSSH 8.9 release on Windows, there is native support for FIDO2 authenticators (like Yubikey) for authentication using some new SK key formats. Background information here: https://developers.yubico.com/SSH/Securing_SSH_with_FIDO2.html and https://www.openssh.com/txt/release-8.2 and https://man.openbsd.org/ssh-keygen.1#FIDO_AUTHENTICATOR

  • New Terms: Resident credentials are called “discoverable credentials” in CTAP 2.1.
  • Supports: YubiKey Firmware 5.2.3+ (Security Key and Yubikey 5+) or Solokey(v2) Firmware 20220822+ or Windows Hello (tested on latest Win11 22H2, but documented feature on Win10 1903+)
FIDO Device FIDO Device Version Key Algorithms [Non-]Resident Notes
Yubikey Neo f/w 3.4.9 ecdsa-sk Non-Resident
Yubikey 5 f/w 5.1.1 ecdsa-sk Non-Resident
Yubikey 5 f/w 5.2.3+ ed25519-sk ecdsa-sk Both
Yubikey FIDO U2F Security Key (BLUE) f/w 3.0.0 ecdsa-sk Non-Resident
Yubikey FIDO2 Security Key NFC (BLUE) f/w 5.4.3 ed25519-sk ecdsa-sk Both
Solo 2 f/w 20220822+ ed25519-sk ecdsa-sk Both Update your firmware from solo
Windows Hello FIDO Win10 1903+/Win11 ecdsa-sk Non-Resident Requires Windows Hello (pin/bio/face) to be enabled in OS
  1. Check your OpenSSH client version and make sure it is new enough ssh -V
  2. Generate the keys using ssh-keygen utility from the command line using supported algorithm and resident parameters.
  • Example 1: Generate the ed25519-sk key on the Yubikey (Resident/Discoverable). Replace FIDO2_Y5C with your own friendly name for your Yubikey in example below: ssh-keygen -t ed25519-sk -O resident -O application=ssh:FIDO2_Y5C -O verify-required (This will prompt for PIN and touch)
  • Example 2: Generate the ecdsa-sk key on Windows Hello. This is non-resident only (see table above) ssh-keygen -t ecdsa-sk You will be prompted for authentication via Face/Fingerprint/PIN in a Windows dialog.
  • Notes: This will generate the private key with a specific SSH_SK_VERSION_MAJOR embedded, and you may only be able to extract the private key on a different host when the version is the same (or when OpenSSH SSH_SK_VERSION_MAJOR is stable) Moving the public key around to different versions should not be an issue. YMMV. Windows ssh-keygen 8.9 and FreeBSD ssh-keygen 9.0 seem to be compatible. The purposeful changes to the middleware interface/version happened at OpenSSH version 8.4 and 8.9. ecdsa-sk key type supports a wider group of FIDO hardware in non-resident mode, including Windows 11 Hello built-in capabilities when paired with fingerprint, facial recognition and/or pincode authentication.
  1. Copy resultant public key to remote host as desired: (Change user@host to applicable remote host) scp ~/.ssh/id_ed25519_sk.pub user@host: ssh user@host (authenticate with password one last time) cat id_ed25519_sk.pub >> ~/.ssh/authorized_keys or as a one-liner: bash --verbose -c "ssh-copy-id -i id_ed25519_sk user@host" (If you have wsl/bash installed). There is not yet a native windows ssh-copy-id shell script distributed with OpenSSH for Windows.
  2. (optional) Extract resident key from Yubikey on a new local box for use with FIDO2/SSH: ssh-keygen -K (Run as administrator from elevated powershell if you get "invalid format" error message XXX:BUG)
  • Rename your private and public key files appropriately to match ssh_config of id_ed25519_sk[.pub] and copy to .ssh/folder.
  • Note: The relevant error message when calling ssh-keygen with disparate variants is "invalid format" on windows and "unsupported xxxx" on FreeBSD/Linux. This is also likely a XXX:BUG, as SSH_SK_VERSION_MAJOR increments should be detectable with a user-friendly error message.
  1. (debugging; not required for functionality) FIDO2 diagnostics using fido2-token
  • Download Windows installation package: https://developers.yubico.com/libfido2/Releases/ fido2-token -L (To list out current FIDO2 tokens and associated devicenames) fido2-token -I <device> (To show current device configuration and capabilities)
  • e.g.: fido2-token -I "\\?\hid#vid_1050&pid_0407&mi_01#c&bd1eba&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}" fido2-token -L -r <device> (To show currently configured resident credentials for FIDO eg: ssh:FIDO2_Y5C)
@L-Schwarz
Copy link

Note: If you want to use the resident fido2 key on windows, you have to name the file with the following pattern: id_ed25519_sk(.pub), other naming conventions of the private key file need to be stated explicit within the command, which uses the identityfile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment