YubiKey GPG setup updated
Overview
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
.
Requirements
- YubiKey 5, any model
- Tails
- Two new USB keys
Preparation steps
Use the 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 :
/mnt/master
/mnt/dirty
Where 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
GPG setup
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
Yubikey setup
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 --edit-card
.
At the gpg/card>
prompt type admin
, you will be prompted for the password in the next step.
Next we change the key attributes via the key-attr
command.
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 list
command.
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 <brendanhoran@basstech.net>" ed25519 sign 0
I don't want my master key to expire, hence the time value of 0
.
The output of the above command looks like this :
gpg --quick-gen-key "Brendan Horan <brendanhoran@basstech.net>" 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 <brendanhoran@basstech.net>
I then export my secret keys as a backup :
gpg -a --export-secret-keys AA2BF3D687A2E671610587E460932F9ECAA57A91 > $GNUPGHOME/master_key.txt
Addition ID's
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: brendan@horan.hk
Comment:
You selected this USER-ID:
"Brendan Horan <brendan@horan.hk>"
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 ultimate
.
Ensure you only have one ID toggled active as indicated by an *
after the ID index number. Then issue the trust
command.
Output of the trust
command looks like :
[ultimate] (1). Brendan Horan <brendanhoran@basstech.net>
[ unknown] (2)* Brendan Horan <brendan@horan.hk>
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.
Subkeys
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 <brendanhoran@basstech.net>
uid [ultimate] Brendan Horan <brendan@horan.hk>
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.