Using a Yubikey 4 on Windows
These are my notes on how to set up GPG with the private key stored on the hardware Yubikey. This will reduce the chances of your GPG private key from being stolen, and also allow you to protect other secrets such as SSH private keys.
It's just some notes and a partial worklog for now, but I may turn it into a full blog post later.
- Using a Yubikey 4 on Windows
- Software needed
- Initialize smartcard support on yubikey
- Creating initial GPG key
- Setting up second machine with GPG
- Using GPG for Putty SSH logins
- Using GPG for OpenSSH logins
- Using GPG for OpenSSH logins in WSL
- Authenticating to GitHub
- Things that I wish worked
Initialize smartcard support on yubikey
C:\Program Files\Yubico\YubiKey Manager>ykman piv reset WARNING! This will delete all stored PIV data and restore factory settings. Proceed? [y/N]: y Resetting PIV data... Success! All PIV data have been cleared from your YubiKey. Your YubiKey now has the default PIN, PUK and Management Key: PIN: 123456 PUK: 12345678 Management Key: 010203040506070801020304050607080102030405060708 C:\Program Files\Yubico\YubiKey Manager>ykman piv change-pin Enter your current PIN: Enter your new PIN: Repeat for confirmation: New PIN set. C:\Program Files\Yubico\YubiKey Manager>ykman piv change-puk Enter your current PUK: Enter your new PUK: Repeat for confirmation: New PUK set.
Creating initial GPG key
Setting up second machine with GPG
curl -o public.asc https://keybase.io/patricklang/pgp_keys.asc gpg --import < public.asc gpg: key F31D4603A5140034: public key "Patrick Lang <email@example.com>" imported gpg: Total number processed: 1 gpg: imported: 1 gpg --edit-key F31D4603A5140034 rem run "trust", "5", y, "quit"
Using GPG for Putty SSH logins
A partial official guide: https://developers.yubico.com/PGP/SSH_authentication/Windows.html
- Install Putty https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
%APPDATA%\gnupg\gpg-agent.confwith a single line
"enable-putty-support" | Out-File -Encoding ascii $ENV:APPDATA\gnupg\gpg-agent.conf
C:\Program Files (x86)\GnuPG\bin\gpg-agent.exe
- Get the public key
gpg --export-ssh-key <email>
- Add that to
~/.ssh/authorized_keyson the remote machine or set it when creating your VM
- Connect from Putty.
- Go to SSH settings, Auth, check
Allow agent forwardingif you want to connect to other VMs or GitHub using the same key
- It should ask you for the the smartcard PIN in a separate window.
- The Yubikey serial will be shown as its connecting so you can check that it used the right key
Authenticating with public key "cardno:0006..." from agent
Using GPG for OpenSSH logins
Once gpg-agent is running, you can start up a proxy that will forward from a named pipe that OpenSSH can use to gpg-agent's pageant proxy. That's a lot of indirection so you need to start things up in the right order.
wsl-ssh-pageant-amd64.exe from benpye/wsl-ssh-pageant I put
wsl-ssh-pageant-amd64.exe in the same directory as Putty for convenience.
- Set up a user environment variable
\\.\pipe\ssh-pageant. If you save it in your user profile you only need to do this once
- Start up gpg-agent (see previous section)
start "C:\Program Files (x86)\PuTTY\wsl-ssh-pageant-amd64.exe" "--winssh ssh-pageant --systray"
- Now, you can use
ssh.exeincluded in Windows
If you want to use headless apps (like VSCode remote), be sure to log in at least once with
ssh.exe to make sure the Yubikey is unlocked.
Visual Studio Code & remote SSH
Put a host entry in
~/.ssh/config on your Windows machine:
Host linuxdevbox User patrick HostName somevm.azure.com ForwardAgent yes
Then you can go to the Remote-SSH pane, right click and connect to the remote host.
ForwardAgentdoesn't currently work as expected. If you use SSH to authenticate to GitHub, then you won't be able to push or fetch from GitHub. You will need to do that manually in another
Using GPG for OpenSSH logins in WSL
TODO - the steps above to fix OpenSSH should work but you need to set agent vars in WSL
Authenticating to GitHub
From a Linux VM
If you're connecting to a Linux machine and running
git there, then follow the steps in (#Using-GPG-for-SSH-logins). Once logged in you can go ahead and use the same key for authentication to GitHub, no extra steps needed.
From your Windows machine
TODO: reconfigure Git for Windows with putty instead of openssh link
If you install from git-scm.org, one of the pages in the setup wizard will detect that you have saved Putty sessions, and ask if you want to use plink.exe instead of OpenSSH.
This works, but there is a problem with console redirection the first time you connect to a server.
git clone firstname.lastname@example.org:ea181db63ada86a2b781cfee0c629c66.git Cloning into 'ea181db63ada86a2b781cfee0c629c66'... The server's host key is not cached in the registry. You have no guarantee that the server is the computer you think it is. The server's rsa2 key fingerprint is: ssh-rsa 2048 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 If you trust this host, enter "y" to add the key to PuTTY's cache and carry on connecting. If you want to carry on connecting just once, without adding the key to the cache, enter "n". If you do not trust this host, press Return to abandon the connection. Store key in cache? (y/n)
This will hang, only ctrl-c works. As a workaround, run
putty.exe -ssh user@server and accept the host key. You don't need to actually log in. Try the
git operation again and it will work.
Git fails to auth after reattaching to a tmux sessino
GPG-Agent not working in Putty on one machine
On one of my systems, putty was failing even with gpg-agent.exe running
--------------------------- PuTTY Fatal Error --------------------------- Pageant failed to answer challenge --------------------------- OK ---------------------------
Since it's the machine where I generated the private key (before moving it to the Yubikey), it wasn't giving me the challenge. Deleting it and reimporting it with just the public key solved the problem.
Conflicts with Windows Hello / Virtual Smart Card
On one system that I had to update the configuration for Kleopatra to work correctly. On that system I enabled verbose logging (Settings > Configure Kleopatra > GnuPG System > Set debugging level to 4, set file path) and looked at the logs to see that it detected two smart cards. In the same dialog I had to set "Connect to card reader at port N" to
Yubico Yubikey 4 OTP+U2F+CCID 0. That was stored in
$ENV:APPDATA\gnupg\scdaemon.conf so it should affect all GPG programs
The Windows tool
certutil.exe -scinfo also shows that as a smart card reader, with the other being "Windows Hello for Business" since this machine is Intune managed.
certutil -scinfo The Microsoft Smart Card Resource Manager is running. Current reader/card status: Readers: 2 0: Windows Hello for Business 1 1: Yubico Yubikey 4 OTP+U2F+CCID 0 --- Reader: Windows Hello for Business 1 --- Status: SCARD_STATE_PRESENT --- Status: The card is available for use. --- Card: Identity Device (Microsoft Generic Profile) ... --- Reader: Yubico Yubikey 4 OTP+U2F+CCID 0 --- Status: SCARD_STATE_PRESENT | SCARD_STATE_EXCLUSIVE | SCARD_STATE_INUSE --- Status: Card is in use exclusively by another process. --- Card: Identity Device (NIST SP 800-73 [PIV]) ...
Unresolved: Using Yubikey from a remote Windows machine
The Remote Desktop protocol can share a smart card, but it seems that it's locked exclusive if you're using gpg-agent on the machine with the Yubikey plugged in.
C:\Program Files (x86)\GnuPG\bin>gpg.exe --card-status gpg: selecting openpgp failed: No such device gpg: OpenPGP card not available: No such device C:\Program Files (x86)\GnuPG\bin>certutil -scinfo The Microsoft Smart Card Resource Manager is running. Current reader/card status: Readers: 1 0: Yubico Yubikey 4 OTP+U2F+CCID 0 --- Reader: Yubico Yubikey 4 OTP+U2F+CCID 0 --- Status: SCARD_STATE_PRESENT | SCARD_STATE_EXCLUSIVE | SCARD_STATE_INUSE --- Status: Card is in use exclusively by another process. --- Card: --- ATR: 3b f8 13 00 00 81 31 fe 15 59 75 62 69 6b 65 79 ;.....1..Yubikey 34 d4 4. ======================================================= Analyzing card in reader: Yubico Yubikey 4 OTP+U2F+CCID 0 SCardGetCardTypeProviderName: The system cannot find the file specified. 0x2 (WIN32: 2 ERROR_FILE_NOT_FOUND) Cannot retrieve Provider Name for SCardGetCardTypeProviderName: The system cannot find the file specified. 0x2 (WIN32: 2 ERROR_FILE_NOT_FOUND) Cannot retrieve Provider Name for --------------===========================-------------- CertUtil: -SCInfo command FAILED: 0x2 (WIN32: 2 ERROR_FILE_NOT_FOUND) CertUtil: The system cannot find the file specified. C:\Program Files (x86)\GnuPG\bin>gpg.exe --card-status gpg: selecting openpgp failed: No such device gpg: OpenPGP card not available: No such device
- SSH proxy timeouts - make sessions persist or expire
- Touch to unlock smartcard instead of PIN
Things that I wish worked
If you find more info on any of these, please drop a comment :)
- Linux tools run in WSL. There's no way to attach a Yubikey device to a WSL instance.
- Logging into a remote Windows Server with Yubikey as a smart card, without Active Directory.