Configuring YubiKey for GPG and U2F

Here is a little walkthrough on how to get started with the YubiKey and GPG. After following this guide you will have a secure setup using a YubiKey containing your GPG keys as well as an authentication key that could be used for SSH. Moreover the configured YubiKey will also be capable of U2F and managing a password store (for examples, see pass and gopass).

I won’t get into all the reason why YubiKeys are great, but if you want to increase the security of your workflow with an additional factor (GPG encryption, secure SSH key, password management, …), this key is the way to go. For more info see the complete list of features under this link.

Good (and open source) solutions for managing your passwords are pass or gopass for example that work great with the GPG/YubiKey.

Note that there’s currently a 20% discount on YubiKeys if you have a github account: !

The below steps will go through the creation of the GPG keys and how to transfer them to the YubiKey.

Air-Gapped Key Generation

In order to do things properly, the GPG key generation process needs to be performed on an air-gapped system (live CD, etc.) disconnected from all networks. In this walkthrough a live CD of Ubuntu 16.04 desktop is used. Download the live CD here:

Make sure to verify the checksum of the downloaded ISO (for Ubuntu 16.04, checksums are available here).

Two USB keys are also needed, one to boot the live CD and one to hold the required packages (as described below). Also, if you plan on backing up your master key (and I hope you do), you’ll need one additional device.


Some packages need to be installed on the live CD. These tools allow you to connect and manage the YubiKey.

Since the live CD is to be air-gapped, the deb files (and their dependencies) must be downloaded from another host beforehand and transferred to the live CD (make sure to use the same distribution/version as the live CD you downloaded). The below script can be used to download the debs and their dependencies for Ubuntu 16.04. Save the script to the file

folder=`mktemp -d`
packages="scdaemon yubikey-personalization libccid pcscd rng-tools"

cd $folder
for p in $packages; do
 echo -e "\n====> downloading \"$p\""
 apt download $p
 apt-cache depends -i $p | awk '/Depends:/ {print $2}' | grep -v '^<' | xargs apt-get download
echo -e "\nPackages available in \"$folder\""

On Ubuntu, when using a live CD to download the debs, make sure to enable the universe package repository with

sudo add-apt-repository universe

Modify the file for execution and then run it:

chmod +x

Also the version of ykpersonalize packaged for Ubuntu (at least for 16.04) is not able to handle newer versions of the YubiKey. You will thus need to use the Yubico’s PPA as described here:

sudo add-apt-repository ppa:yubico/stable
sudo apt-get update

The script will output the folder in which all those debs have been downloaded. Copy those to a USB stick.  You will also need the script to enable the touch to sign/encrypt/auth feature from within the live system.

The downloaded deb files will then have to be transferred to the live system (with a USB key, for example). Once copied, install them by running dpkg from the location you put the files in:

$ sudo dpkg -i *.deb

If you feel uncomfortable copying the debs on the air-gapped system, read the following wiki page on Ubuntu’s package authentication:

The tool rng-tools will be used on the live system to increase the entropy when generating the keys. Don’t forget to start it once installed:

$ sudo rngd -r /dev/urandom

Key generation

Now comes the heavy part: generating the keys on the live system. The first step is to create a working folder to use with GPG:

$ export GNUPGHOME=$HOME/workspace
$ mkdir -p $GNUPGHOME && chmod 700 $GNUPGHOME

This folder (replace $HOME/workspace with anything you want) will need to be backed up on a secure medium/place (preferably disconnected) at the end of this walkthrough in case anything happens to your keys.

Besides generating a master key, three subkeys will be created. These are the keys that will be moved to the YubiKey:

  • sign-only subkey: used to sign with GPG
  • encryption subkey: used to decrypt with GPG
  • authentication subkey: used to authenticate (SSH for example)

Generate the Master Key

The first step is to generate a master key. This key will then be used to generate the different subkeys that will be transferred to the YubiKey. The master key itself won’t be pushed to the YubiKey and should be kept safe in a backup storage location.

$ gpg2 --full-gen-key

Select (4) for RSA sign only and choose an appropriate size (4096 bits to be safe) and an expiration (or none if not needed). Then enter your name, email address and a comment. Add a passphrase if you expect to copy the master key anywhere else.

The ID of the master key can be retrieved with the following commands. This ID will be used for later commands when KEYID is specified:

$ gpg2 --list-secret-keys # get secret keys
$ gpg2 --list-keys # get public keys

Create the Revocation Certificate

In case one of the keys gets compromised, a revocation certificate will be needed to revoke it. This can be done now or later, but since we are here, let’s create one:

$ gpg2 --output $GNUPGHOME/revocation-certificate.txt --gen-revoke KEYID

When prompted, select reason 1 (Key has been compromised) and add a comment.

Generate a Sign-Only Subkey

$ gpg2 --expert --edit-key KEYID

The command addkey is to be used to add a new key to the keyring. The type of key to select is 4 for RSA sign only. Choose the size of the key (4096 bits preferably), the expiration and then validate with twice y and save your key with save.

Generate an Encryption Subkey

$ gpg2 --expert --edit-key KEYID

Again the command is addkey to create a new key. Select 6 for RSA encrypt only, a size and an expiration. Validate with twice y and save your key with save.

Generate an Authentication Subkey

$ gpg2 --expert --edit-key KEYID

Add one last key with the command addkey, but this time the capabilities will have to be set manually. Select 8 for “RSA set your own capability” and toggle the authentication capability only by playing with the selection until you reach the following:

Current allowed actions: Authenticate

Then finish with q and choose a size and an expiration. Validate with twice and save your key with save.

Check the Key Ring

Make sure you have one master key and three subkeys in your key ring with the following commands:

$ gpg2 --list-secret-keys # list the secret keys
$ gpg2 --list-keys # list the public keys

Export the Public Key

The public key can be exported using the following command:

$ gpg2 -a --export KEYID > public-key.asc

This key can then be published on a key server or later imported on your everyday system with:

$ gpg2 --import < public-key.asc

Setup the YubiKey

Now that all keys have been generated, it’s time to push them to the YubiKey.

First make sure the YubiKey gets detected by issuing the following command. Also ensure the serial displayed matches the one of the key:

$ gpg2 --card-status

If your key is not detected (Card not present), try restarting the pcscd service:

$ sudo service pcscd restart

OTP mode needs to be disabled on the key with ykpersonalize:

# delete slot 1 (OTP per default)
$ ykpersonalize -1 -z

After the above command, you need to unplug and plug in your key for the new mode to be recognized.

Then the new mode can be checked under dmesg or with

## check mode in the idProduct field
$ lsusb -v

For more info, see these links:

Setup the YubiKey

The first step is to change the admin PIN (per default set to 12345678) and the user PIN (per default set to 123456):

$ gpg2 --card-edit
> admin
> passwd

Then quit the admin panel with q and edit the different fields of the YubiKey (name, login,  url, sex, lang, …). Terminate with q.

For a complete explanation of all the available fields, have a look at

Move GPG keys to the YubiKey

Be aware that this operation is destructive, that is the keys pushed to the YubiKey will be effectively deleted from the file system, thus make sure to do a backup beforehand of your $GNUPGHOME folder.

$ cp -r $GNUPGHOME{,.bak}

The above created folder (with the .bak suffix) is the one that is to be backed up on a safe storage.

Now the keys will be moved to the YubiKey. Each key needs to be toggled (using the command key followed by its ID) and pushed to the card (using the command keytocard). Double check that the right key is pushed to the right slot on the YubiKey.

$ gpg2 --edit-key KEYID
> key 1
> keytocard
> 1
> key 1
> key 2
> keytocard
> 2
> key 2
> key 3
> keytocard
> 3
> save

For more info, see

Check that all your keys have been pushed to the YubiKey with

$ gpg2 --card-status

Enable Touch-to-Sign

Using the script (downloaded from here) one can enable the touch-to-sign feature of the YubiKey for accessing the different keys.

## enable touch to sign
$ ./ sig on
## enable touch to authenticate
$ ./ aut on
## enable touch to decrypt
$ ./ dec on

For more see

Final Step

Now that everything is setup, make sure to backup the $GNUPGHOME backup folder  (${GNUPGHOME}.bak) in a safe place (disconnected), exit the live system and start using the YubiKey on your everyday system.

Install the required packages and insert the key:

## for ubuntu/debian
$ sudo apt-get -y install scdaemon libccid gnupg2 pcsc-tools yubikey-personalization
## for arch
$ sudo pacman -S pcsc-tools ccid libusb-compat yubikey-personalization
$ sudo systemctl enable pcscd.service
$ sudo systemctl start pcscd.service

The YubiKey is detected with the following command, which should list its features and the different keys available:

$ gpg2 --card-status

To use the authentication key for SSH, ensure you have properly setup gpg-agent to handle SSH keys and issue the following command, which will output the SSH public key:

$ ssh-add -L

Debian Troubleshooting

On debian/testing a conflict exists between gpg-agent/gpg2 and pcscd. The following needs to be run for the YubiKey to work:

$ sudo apt-get remove --purge pcscd

and add a new udev rule under /etc/udev/rules.d/90-yubikey.rules

ATTRS{idVendor}=="TODO", ATTRS{idProduct}=="TODO", MODE="664", GROUP="plugdev"

Adapt the TODOs with the output of the lsusb command. Then remove and reinsert the YubiKey.



  1. You can leave your comment or question here, and your email if you’d prefer a private contact.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s