Most guides are from a Linux perspective. This guide is a short and straight to the point guide containing just the commands aimed at Windows. This assumes you are familiar with GPG’s concepts and just want to configure your YubiKey as quickly as possible.

Prerequisites

Download and install the following:

Initial setup

Master key

Generate a passphrase:

gpg --gen-random --armor 0 24

Generate a master key:

gpg --expert --full-generate-key

Select

  • Choose RSA (set your own capabilities)
  • Toggle so just Certify is enabled
  • Choose 4096 for the keysize
  • Enter your name and primary email

A dialog will appear. Enter the passphrase you generate earlier.

pub   rsa4096 2022-10-25 [C]
      {some long value}
uid                      Chandler Newman <[email protected]>

The long value in the above output is your master key id.

Create child keys

Start by opening your key for editing:

gpg --expert --edit-key $MASTER_KEY_ID

Create your signing key:

  1. Type addkey
  2. Enter master passphrase in popup
  3. Select RSA (sign only)
  4. Choose 4096 for the key size
  5. Enter a suitable expiry time 1y
  6. Confirm changes

Repeat the above, choosing RSA (encrypt only) to create an encryption key.

Create your authentication key:

  1. Type addkey
  2. Enter master passphrase in popup
  3. Select RSA (set your own capabilities)
  4. Toggle so only Authentication is enabled
  5. Choose 4096 for the key size
  6. Enter a suitable expiry time 1y
  7. Confirm changes

Save the new keys by typing:

save

Add additional identities

Start by opening your key for editing:

gpg --expert --edit-key $MASTER_KEY_ID
  1. Type adduid
  2. Enter your name and other email address
  3. Trust your identity by typing trust and choosing I trust ultimately
  4. Enter uid 1 and then primary to keep the original identify as the primary

Save the new identities by typing:

save

Export keys

Generate a backup of your master key:

gpg -o mastersub.gpg --armor --export-secret-keys $MASTER_KEY_ID
gpg -o sub.gpg --armor --export-secret-subkeys $MASTER_KEY_ID
gpg --output revoke.asc --gen-revoke $MASTER_KEY_ID

Create a copy of %appdata%/gnupg. Use some for of encryption (e.g. password protected zip).

Store these safely. The master key will still be encrypted with the master passphrase, so back this up too.

Export public key:

gpg -o pubkey.gpg --armor --export $MASTER_KEY_ID

Upload public key:

gpg --send-key $MASTER_KEY_ID

Move to YubiKey

Configure YubiKey

Insert YubiKey and:

  1. Enter edit mode gpg --card-edit
  2. admin to enable admin commands
  3. kdf-setup to enable pin hashing
  4. Change pin’s from defaults
  5. passwd, select change admin pin
  6. Old admin pin: 12345678
  7. Choose a new admin pin. This can be a full password.
  8. Select change pin
  9. Old pin: 123456
  10. Your pin will be used day-to-day, while the admin pin is for configuration.
  11. Configure basic settings via the following commands: name, lang, login
  12. Check values via list
  13. quit once done

Move keys

Start by opening your key for editing:

gpg --expert --edit-key $MASTER_KEY_ID

Move each key, one by one:

  1. key 1 to select key 1
  2. keytocard
  3. Select slot (Signature key for signing key)
  4. key 1 to deselect key 1

Repeat for key 2 and key 3, selecting the single possible slot.

Save changes:

save

Verify move:

gpg -K

The 3 sub keys should show as ssb>.

Additional YubiKeys

Delete %appdata%/gnupg and restore earlier backup. Repeat the above 2 steps.

Only a single YubiKey can be configured at once. If you switch between your primary and backup YubiKey, use

gpg-connect-agent "scd serialno" "learn --force" /bye

to relearn which key to use.

Cleanup

Remove traces of master key:

Delete %appdata%/gnupg

gpg --delete-secret-key $MASTER_KEY_ID

Setting up key on a Windows device

Now that the YubiKey is configured, we can now setup the key on a device.

Reimport public key:

gpg --import pubkey.gpg 

or

gpg --recv $MASTER_KEY_ID

Start agent:

gpg-connect-agent /bye

Configure agent by creating %APPDATA%\gnupg\gpg-agent.conf

enable-putty-support
enable-ssh-support
use-standard-socket
default-cache-ttl 600
max-cache-ttl 7200

Restart agent:

gpg-connect-agent killagent /bye
gpg-connect-agent /bye

This gpg-agent replaces your usual pagent, as pagent does not support gpg.

Find authentication key id

gpg --card-status

Remove spaces to get the id.

Export ssh public key:

gpg --export-ssh-key $AUTHENTICATION_KEY_ID

Add the ssh public key and gpg public key from earlier to your GitHub account. Add your public key to your authorised_key on your remote server like usual.

At this point, putty should work. You should get a PIN popup when trying to connect to a host.

However, commands like git and ssh will still not work.

Configure auto starting:

  • Create a shortcut to C:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe in C:\Users\USER\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Start-up.
  • Edit Target property to contain /bye at the end.

Fixing native ssh agent:

  • Move wsl-ssh-pageant-amd64-gui.exe into C:\wsl-ssh-pageant
  • Create shortcut to this file and add to start-up like above.
  • Replace Target with: C:\wsl-ssh-pageant\wsl-ssh-pageant-amd64-gui.exe --wsl C:\wsl-ssh-pageant\ssh-agent.sock --winssh ssh-pageant --systray
  • Double click new shortcut to start wsl-ssh-pageant. Should now appear in tray.
  • Add a user or system wide environment variable: SSH_AUTH_SOCK set to \\.\pipe\ssh-pageant

Check everything now works:

ssh-add -L

Your ssh public key should now be listed.

TODO

  • gpg commit signing
  • gpg forwarding over ssh

Resources