Applying GPG and Yubikey: Part 6 (Setting up Yubikeys)

As a reminder, you can check out my overview post if you’re curious about why and in what ways I started using GPG and Yubikey. If you haven’t set up your GPG keys yet, I also talk about a simple flow in my second post.

Today, we’re diving into setting up your Yubikey to host your GPG subkeys created in parts 3, 4, and 5.


I’ve got multiple Yubikeys configured across different devices and primarily use them for password management and SSH authentication. Rather than keeping physical subkeys on each of these machines, I instead have a dedicated Yubikey for each device that hosts the subkeys, keeping them protected from direct exposure.

GPG Subkeys

In order to have a simpler setup, I maintain a single encryption, signing, and authentication subkey set that is copied to each of my Yubikeys. By design, when you move a subkey over to a Yubikey, the local instance is destroyed. To maintain the same subkey, you have to copy your GPG folder prior to transferring the keys in order to maintain the subkeys.

Alternatively, you can opt to not save your changes during the interactive CLI, but it’s very subtle and I tend to forget every time.

When a Yubikey is plugged in without any keys configured, running gpg --card-status should reflect something like this:

Reader ...........: Yubico YubiKey CCID
Application ID ...: D2760001240103040006144075690000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Yubico
Serial number ....: 14407569
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: not forced
Key attributes ...: rsa2048 rsa2048 rsa2048
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]

Notice how the signature, encryption, and authentication keys are all marked as [none]!

Moving subkeys to yubikey

The act of transferring a subkey over to a Yubikey is destructive, and will result in a stub remaining on the local machine that does nothing without access to the Yubikey itself. Below are the steps I take to transfer each subkey one at a time:

  1. We need to edit the local key via gpg --expert --edit-key [email protected]
  2. Make sure to select the proper key using key 1 or whatever number corresponds to the subkey. When this is done, a * will appear next to the key
  3. Enter keytocard, which will prompt for the master secret key password (this is for the master key, not the yubikey) and then the yubikey admin password, which is 12345678 by default
  4. Do the same for each other subkey by deselecting the current subkey (e.g. key 1 again) and then selecting the next subkey (e.g. key 2)
  5. Enter quit and say y to the prompt to save the changes and produce local stubs

Adding details such as public key URL and name to Yubikey

Out of the box, your Yubikey comes with no information and a default admin password and regular password.

  • The admin password is used to change your regular password and transfer GPG keys over to the Yubikey.
  • The regular password is used for authentication whenever your computer needs to leverage a key stored on your Yubikey.

Whenever I’m setting up a new Yubikey, here are the steps I take:

  1. We need to edit the card via gpg --expert --edit-card
  2. Access the admin commands via admin
  3. Use passwd to change the passwords
    • To change the regular password, use 123456 as the default and then provide the new password
    • To change the admin password, use 12345678 as the default and then provide the new password
  4. Use url to change the url. I use as the public key url.
    • Providing this enables us to pull in the public keys for a new Yubikey automatically via fetch!
    • Setting this requires re-entering the admin Yubikey password.
  5. Use name to change the surname (Senkbeil) and given name (Chip).
  6. Use lang to change the language to English (en).
  7. Enter quit to exit and save changes

Removing master key from local system

With the subkeys moved over to our Yubikey, it’s a good idea to remove the master key from our local system. You should have a backup of this either in a paper form or in a secure storage you trust! I only use my master key to manage subkeys, delegating all other operations to the subkeys themselves.

To remove the master key, we want to delete the local secret key using gpg --delete-secret-key <ID> where I used [email protected] as it matches one of my identity’s email addresses.

When this is done, gpg -K will be blank. This means that we need to re-import our key information. To do this, edit our card using gpg --expert --edit-card.

From there, since we have the public key available and defined in the url, we can run fetch to get and import the information.

Now, gpg -K should reflect the private master key with a # to indicate not locally available and > for subkeys to imply the same.

Disabling OTP

By default, the Yubikey will be sensitive to touch as it attempts to provide a one-time password (OTP). Since I don’t use that functionality myself, I’d prefer to disable it so I don’t accidentally activate it when brushing the key with my leg when using a laptop. To do this, I need to install the yubikey manager to configure it:

arch -arm64 brew install ykman

From there, I’m able to see a connected Yubikey via ykman info and the modes it has (OTP/FIDO/CCID). For OpenPGP applications, we need CCID

a. Setting the modes is done using a string in the form of

ykman mode OTP+FIDO+CCID and providing just ykman mode CCID will configure the Yubikey to only be configured for CCID applications.

Doing so, ykman info should now reflect the following:

Device type: YubiKey 5C Nano
Serial number: 14407569
Firmware version: 5.2.7
Form factor: Nano (USB-C)
Enabled USB interfaces: CCID

OTP             Disabled
FIDO U2F        Disabled
OpenPGP         Enabled
PIV             Enabled
OATH            Enabled
FIDO2           Disabled

What’s next?

In the next post, I’ll be explaining how to set up NFC on an Android device to leverage your Yubikey for password management in conjunction with password store.