7374756666

Using Yubi keys for GPG/SSH keys

I've recently replaced my GPG keys with new ones stored on Yubi keys, why? Well...

  1. To use a master key and sub keys, previously I only had a master key
  2. To make the keys portable (no need to copy them to all machines)
  3. To enable SSH compatability
  4. It was fun

Step 1 - Prepare the system

sudo add-apt-repository ppa:yubico/stable
sudo apt-get update
sudo apt-get install yubikey-personalization yubikey-personalization-gui

Step 2 - Prepare the yubi keys

Step 3 Generate the new master key and revocation certificate

Either on a new machine/air gapped machine/live usb whatever your preference is depending on your paranoia run the following:

export GNUPGHOME=$(mktemp -d)

if it's in /tmp (probably) and won't interfere with any existing keys so you can nuke the folder if you make a mistake.

Now run:

cd $GNUPGHOME
export GPG_TTY=$(tty)
cat <<EOT > gpg.conf
keyserver hkps://hkps.pool.sks-keyservers.net
auto-key-locate keyserver
personal-cipher-preferences AES256 AES192 AES CAST5 CAMELLIA256 CAMELLIA192 CAMELLIA128
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256
keyid-format long
EOT
gpg2 --full-gen-key

You can add extra uids using gpg2 --edit-key $KEYID then adduid once all have been added use the uid N replacing N with the uid index you want to be the primary, then run primary to make the uid primary, finally run save

To generate a revocation certificate run

gpg --gen-revoke $KEYID > $GNUPGHOME/revoke.txt

Step 4 Generate sub keys

Run gpg2 --expert --edit-key $KEYID

Enter addkey Choose option 4 for signing keys, option 6 for encryption keys and option 8 followed by S E A to disable signing and encyrption and enable authentication for keys to be used for SSH.

Yubi keys only support 2048 bit RSA keys which is perfectly fine at the time of writing.

Run the save command and now you have all your keys ready.

Step 5 Export the secret keys

Export the master and sub keys with gpg2 --armor --export-secret-keys $KEYID > $GNUPGHOME/mastersub.key Export the sub keys with gpg2 --armor --export-secret-subkeys $KEYID > $GNUPGHOME/sub.key

Step 6 backup the private keys important do this before copying keys to the yubi key

Step 7 copy the keys to the card

If you want to use the same key on multiple cards you must restore the tar backup you made earlier tar -xvpf /path/to/encrypted/stick/gpg.tar

Step 8 Export, sign and publish the new key

Some notes

My gpg.conf looks like this

keyserver hkps://hkps.pool.sks-keyservers.net
auto-key-locate keyserver
personal-cipher-preferences AES256 AES192 AES CAST5 CAMELLIA256 CAMELLIA192 CAMELLIA128
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
cert-digest-algo SHA512
s2k-digest-algo SHA512
s2k-cipher-algo AES256
keyid-format long

My gpg-agent.conf looks like this

pinentry-program /usr/bin/pinentry-tty
default-cache-ttl 21600
max-cache-ttl 21600
default-cache-ttl-ssh 1800
max-cache-ttl-ssh 3600
enable-ssh-support

The following in .profile will set up the GPG tty, allow you to use pinentry over ssh and set up the ssh agent socket

#!/bin/bash
# set the gpg tty
export GPG_TTY=$(tty)
# if the gpg agent is running tell it this window is now the pin entry window
if [ -e ~/.gnupg/S.gpg-agent ]
then
    echo 'UPDATESTARTUPTTY' | gpg-connect-agent > /dev/null
fi
# If the ssh auth sock isn't set, set it (note this still allows agent forwarding) and also overrides
# the gnome keychain auth sock
if [ -z "$SSH_AUTH_SOCK" -o "$SSH_AUTH_SOCK" == "/run/user/$(id -u)/keyring/ssh" ]
then
    export SSH_AUTH_SOCK="$HOME/.gnupg/S.gpg-agent.ssh"
fi
# sometimes things can get out of whack, run this function to fix them (handy at first login)
function fixgpgssh() {
    export GPG_TTY=$(tty)
    gpg --card-status > /dev/null
    echo 'UPDATESTARTUPTTY' | gpg-connect-agent > /dev/null
    export SSH_AUTH_SOCK="$HOME/.gnupg/S.gpg-agent.ssh" 
}

References