Skip to content

Instantly share code, notes, and snippets.

@PatrickLang
Last active June 10, 2024 18:36
Show Gist options
  • Save PatrickLang/7be00ba46a43eca3ef64ffe64b494749 to your computer and use it in GitHub Desktop.
Save PatrickLang/7be00ba46a43eca3ef64ffe64b494749 to your computer and use it in GitHub Desktop.
Yubikey + Windows

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.

Software needed

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

https://support.yubico.com/support/solutions/articles/15000006420-using-your-yubikey-with-openpgp#Generating_the_Key_on_Your_Local_System_(Recommended)2u7vh5

Setting up second machine with GPG

https://forum.yubico.com/viewtopic7bd1.html?f=35&t=2446

curl -o public.asc https://keybase.io/patricklang/pgp_keys.asc

gpg --import < public.asc
gpg: key F31D4603A5140034: public key "Patrick Lang <[email protected]>" 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

Steps:

  1. Install Putty https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
  2. Create %APPDATA%\gnupg\gpg-agent.conf with a single line enable-putty-support - PowerShell: "enable-putty-support" | Out-File -Encoding ascii $ENV:APPDATA\gnupg\gpg-agent.conf
  3. Run C:\Program Files (x86)\GnuPG\bin\gpg-agent.exe
  4. Get the public key gpg --export-ssh-key <email>
  5. Add that to ~/.ssh/authorized_keys on the remote machine or set it when creating your VM
  6. Connect from Putty.
  • Go to SSH settings, Auth, check Allow agent forwarding if 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.

First, get 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.

  1. Set up a user environment variable SSH_AUTH_SOCK = \\.\pipe\ssh-pageant. If you save it in your user profile you only need to do this once
  2. Start up gpg-agent (see previous section)
  3. start "C:\Program Files (x86)\PuTTY\wsl-ssh-pageant-amd64.exe" "--winssh ssh-pageant --systray"
  4. Now, you can use ssh.exe included 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

Once you have OpenSSH working, then Visual Studio Code - Insiders and the Remote SSH plugin works.

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.

Issue: ForwardAgent doesn'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 putty or ssh.exe session.

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 [email protected]: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.

Troubleshooting

Git fails to auth after reattaching to a tmux sessino

https://stackoverflow.com/questions/21378569/how-to-auto-update-ssh-agent-environment-variables-when-attaching-to-existing-tm

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

TODOs

  • 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.
@cameri
Copy link

cameri commented Feb 23, 2022

This was great. Thanks!

@justinkb
Copy link

if you've got gpg-agent set up to enable win32-openssh support, you can use

[core]
        sshCommand = 'C:\\Windows\\System32\\OpenSSH\\ssh.exe'

in .gitconfig to use the windows openssh client instead of the ssh client bundled with git for windows, and it'll work and you won't need the plink from putty which comes with some issues you listed

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