YubiKey GPG setup updated
This post follows on from the initial setup post. The aim for this post is around setting up the GPG applet.
A lot of initial choices and methods are based off my original GPG guide. This will cover creating new keys based on elliptic curve cryptography.
I have revoked my previous GPG keys with the finger print of
174D 1B90 066F F847 7A95 E69E 7FB0 D040 76E0 A15A.
- YubiKey 5, any model
- Two new USB keys
Off-line stage section from my Yubikey 5 setup for all steps during this article.
Creating the keys
USB stick setup
Firstly clearly label your USB sticks. One will be used to store our Master key and revocation certificate. This USB stick should never be mounted outside of the secure Tails environment.
The second USB stick will be used to transfer things like our public key to our normal operating environment.
Create the following directories :
master is our first USB stick and
dirty is the second.
Mount each USB stick onto the above directories.
Encrypted master key storage
To store my master keys and other sensitive materials I use a LUKS container. I create a file vs use a raw device like a USB stick to ensure I can copy the LUKS volume to any storage medium.
For example I have this LUKS container backed up on a m-disk blu-ray and on a USB stick in more then one location.
Pass-phrases are stored in my password manager.
Open up a root level terminal and follow the below to create the container.
I create this on the
master USB stick in the following manner.
dd if=/dev/zero bs=1M count=1024 of=/mnt/master/gpg-luks.volume cryptsetup luksFormat /mnt/master/gpg-luks.volume cryptsetup luksOpen /mnt/master/gpg-luks.volume gpg-luks mkfs.ext4 /dev/mapper/gpg-luks mkdir /mnt/luks-crypt mount /dev/mapper/gpg-luks /mnt/luks-crypt
Next we setup where GPG will store its user data. By default this is
~/.gnupg however we want it on our luks container.
We can achieve this via the following commands :
export GNUPGHOME=/mnt/luks-crypt mkdir $GNUPGHOME chmod 700 $GNUPGHOME
We will also need a default config file for GPG.
Again, the settings selected here and why I have selected them are explained in the original guide.
For now create a this file
$GNUPGHOME/gpg.conf, with the following contents :
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128 TWOFISH cert-digest-algo SHA512
The Yubikey from factory is set to store RSA key types, however we want to use elliptic curve keys. Thus we need to edit the card.
Plug in the YubiKey and run the following command
gpg/card> prompt type
admin, you will be prompted for the password in the next step.
Next we change the key attributes via the
I will use
ECC/Curve 25519 over the NIST curve due to security issues with the NIST curves.
It should look similar to this output :
gpg/card> key-attr Changing card key attribute for: Signature key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 2 Please select which elliptic curve you want: (1) Curve 25519 (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: ed25519 Changing card key attribute for: Encryption key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 2 Please select which elliptic curve you want: (1) Curve 25519 (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: cv25519 Changing card key attribute for: Authentication key Please select what kind of key you want: (1) RSA (2) ECC Your selection? 2 Please select which elliptic curve you want: (1) Curve 25519 (4) NIST P-384 Your selection? 1 The card will now be re-configured to generate a key of type: ed25519 gpg/card>
You can then check that the Yubikey is configured correctly via the
Under the section
Key attributes You should see the following :
Key attributes ...: ed25519 cv25519 ed25519
Once done enter
quit to exit the card edit menu.
Master keys and revocation certificate
Now its time to create the new off line master key and revocation certificate. I use the
--quick-gen-key option that takes care of generating the key and the revocation certificate in one step.
Issue the command :
gpg --quick-gen-key "Brendan Horan <email@example.com>" ed25519 sign 0
I don't want my master key to expire, hence the time value of
The output of the above command looks like this :
gpg --quick-gen-key "Brendan Horan <firstname.lastname@example.org>" ed25519 sign 0 We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: /mnt/luks-crypt/trustdb.gpg: trustdb created gpg: key 60932F9ECAA57A91 marked as ultimately trusted gpg: directory '/mnt/luks-crypt/openpgp-revocs.d' created gpg: revocation certificate stored as '/mnt/luks-crypt /openpgp-revocs.d/AA2BF3D687A2E671610587E460932F9ECAA57A91.rev' public and secret key created and signed. pub ed25519 2020-07-12 [SC] AA2BF3D687A2E671610587E460932F9ECAA57A91 uid Brendan Horan <email@example.com>
I then export my secret keys as a backup :
gpg -a --export-secret-keys AA2BF3D687A2E671610587E460932F9ECAA57A91 > $GNUPGHOME/master_key.txt
I like to add additional ID's to my keys, I normally add my most common/most used email addresses as additional ID's.
To do that issue the following command :
gpg --edit-key AA2BF3D687A2E671610587E460932F9ECAA57A91
We then add additional ID's like tis :
gpg> adduid Real name: Brendan Horan Email address: firstname.lastname@example.org Comment: You selected this USER-ID: "Brendan Horan <email@example.com>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
After this the ID will be
unknown, you should give it a trust level. I set this to
Ensure you only have one ID toggled active as indicated by an
* after the ID index number. Then issue the
Output of the
trust command looks like :
[ultimate] (1). Brendan Horan <firstname.lastname@example.org> [ unknown] (2)* Brendan Horan <email@example.com> Please decide how far you trust this user to correctly verify other users keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 5 Do you really want to set this key to ultimate trust? (y/N) y
Once done, issue the
save command to write this to the key.
I use subkeys for my encryption, authentication and signing keys.
This allows me to store them easily on the Yubikey. I set expiry dates on all my subkeys. You can refer back to the original article for more details on why.
To generate sub keys simply run the following :
gpg --quick-add-key AA2BF3D687A2E671610587E460932F9ECAA57A91 cv25519 encr 365d gpg --quick-add-key AA2BF3D687A2E671610587E460932F9ECAA57A91 ed25519 auth 365d gpg --quick-add-key AA2BF3D687A2E671610587E460932F9ECAA57A91 ed25519 sign 365d
Take a look to ensure they where created correctly :
gpg --list-keys /mnt/luks-crypt/pubring.kbx --------------------------------- pub ed25519 2020-07-12 [SC] AA2BF3D687A2E671610587E460932F9ECAA57A91 uid [ultimate] Brendan Horan <firstname.lastname@example.org> uid [ultimate] Brendan Horan <email@example.com> sub cv25519 2020-07-12 [E] [expires: 2021-07-12] sub ed25519 2020-07-12 [A] [expires: 2021-07-12] sub ed25519 2020-07-12 [S] [expires: 2021-07-12]
It is now a good time to take a backup of all the keys.
gpg -a --export-secret-keys AA2BF3D687A2E671610587E460932F9ECAA57A91 > $GNUPGHOME/master_with_subkeys.txt gpg -a --export-secret-subkeys AA2BF3D687A2E671610587E460932F9ECAA57A91 > $GNUPGHOME/subkey_stubs.txt gpg -a --export AA2BF3D687A2E671610587E460932F9ECAA57A91 > $GNUPGHOME/public_key.txt
You should also copy the
public_key.txt to the
dirty usb stick. This is the only section that needs to be transfered to your daily workstation.
Move the subkeys to the Yubikey
Nothing much in this process has changed.
You can follow the previous guide to move the subkeys to the Yubikey.