summaryrefslogtreecommitdiff
path: root/content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md')
-rw-r--r--content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md443
1 files changed, 443 insertions, 0 deletions
diff --git a/content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md b/content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md
new file mode 100644
index 0000000..314ba09
--- /dev/null
+++ b/content/posts/2018/2018-09-04-setting-up-pgp-with-a-yubikey.md
@@ -0,0 +1,443 @@
+---
+title: Setting up PGP with a Yubikey
+date: 2018-09-04
+tags:
+- GPG
+- PGP
+- Security
+- YubiKey
+---
+
+# Setting up PGP with a Yubikey
+
+I've recently started a job where I am required to have above-average security
+practices in place on my machine. I already had some standard security in
+place, such as full disk encryption and PGP encrypted email, but I thought that
+this would be a good time to up my game. To accomplish this, I purchased a
+Yubikey to act as my physical security token. Additionally, I have a USB device
+which is also encrypted to hold backups of the keys.
+
+In this blogpost, I will detail how I set up my security policies in the hopes
+it will be able to help out other people looking to improve their security, and
+to get feedback to improve my set up as well.
+
+{< admonition title="note" >}
+I am using the Yubikey 4. If you're using another version, some steps may
+differ.
+{< / admonition >}
+
+## Installing required software
+
+You'll need some software to set all of this up. Depending on your
+distribution, some of it might already be installed. Everything not installed
+yet should be installed with your distribution's package manager.
+
+For encrypting the disk and the USB key, you will need `cryptsetup`. To
+generate and use the PGP keys, you will need `gpg`, at least version 2.0.12. To
+interface with the Yubikey itself, you'll need `pcsc-lite`, and start the
+service as well. It may be necessary to restart the `gpg-agent` after
+installing `pcsc-lite`, which you can do by simply killing the existing
+`gpg-agent` process. It restarts itself when needed.
+
+To securely remove the temporary data we need, you should make sure you have
+`secure-delete` available on your system as well.
+
+## Personalizing the Yubikey
+
+The Yubikey can be personalized. Some of this personalization is completely
+optional, such as setting personal information. However, setting new PIN codes
+is strongly advised, as the default values are publicly known.
+
+### PIN codes
+
+The PIN codes are short combinations of numbers, letters and symbols to grant
+permission to write to or retrieve data from the Yubikey. The default value for
+the user PIN is `123456`. The admin PIN is `12345678` by default. These should
+be changed, as they're publicly known and allow the usage of your private keys.
+To change these, use the `gpg` program and enter admin mode:
+
+```txt
+gpg --card-edit
+
+gpg/card> admin
+Admin commands are allowed
+```
+
+You'll notice it immediately says that admin commands are now allowed to be
+used. The admin PIN (`12345678`) will be asked whenever an admin command is
+executed. It will then be stored for this session, so you won't have to enter
+it right away. To update the PIN values, run the following commands:
+
+```txt
+gpg/card> passwd
+gpg/card> 3
+```
+
+This will change the admin PIN first. This PIN is required for managing the
+keys and user PIN on the Yubikey. To set the user PIN, pick `1` instead of `3`:
+
+```txt
+gpg/card> 1
+```
+
+Once this is done, you can quit the `passwd` submenu using `q`:
+
+```txt
+gpg/card> q
+```
+
+You may have noticed we skipped the reset code. Resetting the device will wipe
+existing keys, so it's not a serious risk to keep this at the default. The
+private keys will be backed up to an encrypted USB drive, so we can always
+retrieve them and put them back on the Yubikey if ever needed.
+
+### Personal information
+
+The personal information is optional, but could be used by a friendly person to
+find out who a found Yubikey belongs to. They can contact the owner, and send
+the key back. You can set as many of the personally identifying fields as you
+want. If you're interested in setting this information, plug in your Yubikey
+and edit the card information with `gpg`:
+
+```txt
+gpg --card-edit
+```
+
+Once you're back in the GPG shell, you can update your personal information.
+There are 5 attributes that you can set in this way:
+
+- `name`, which is your real name;
+- `lang`, which is your preferred contact language;
+- `sex`, which is your real sex;
+- `url`, which indicates a location to retrieve your public key from;
+- `login`, which indicates your email address.
+
+Each of these attributes can be updated by running the command in the GPG
+shell. For instance, to update your real name, run the following:
+
+```txt
+gpg/card> name
+```
+
+You do not need to explicitly save once you're done. You can run `quit` to quit
+the GPG shell and return to your regular shell.
+
+## Creating PGP keys
+
+To create the PGP keys, we'll create a temporary directory which will function
+as our working directory to store the keys in. This way you can't accidentally
+break existing keys if you have them, and ensure that the private keys don't
+accidentally linger on in your filesystem.
+
+### Preparing a clean environment
+
+To create such a temporary directory, we'll use `mktemp`, and store the result
+in an environment variable so we can easily re-use it:
+
+```sh
+export GNUPGHOME="$(mktemp -d)"
+```
+
+Now you can switch to that directory using `cd "$GNUPGHOME"`. Additionally,
+`$GNUPGHOME` is also the directory `gpg` uses as its working directory, if it
+is set. This means you can use a temporary custom configuration for `gpg` as
+well, without it affecting your normal setup. The following configuration is
+recommended to set in `$GNUPGHOME/gpg.conf` before starting:
+
+```conf
+use-agent
+charset utf-8
+no-comments
+keyid-format 0xlong
+list-options show-uid-validity
+verify-options show-uid-validity
+with-fingerprint
+```
+
+If you have a `gpg-agent` running, it is recommended to stop it before
+continuing with `killall gpg-agent`.
+
+### Creating the master key
+
+For our master key, we'll go for a 4096 bytes RSA key. 2048 would be plenty as
+well, if you want the generation to be a tad quicker. `gpg` will ask you a
+couple questions to establish your identity, which is required for a PGP key.
+You can add more identities later, in case you're using multiple email
+addresses, for instance.
+
+Start the key generation process with `gpg`:
+
+```txt
+gpg --full-generate-key
+```
+
+When asked what kind of key you want, choose `4` (RSA (sign only)). Next is the
+key size, which should be `4096`.
+
+The key's expiration is optional, though highly recommended. It will be more
+effort to maintain the keys, as you'll occasionally need the private master
+keys to extend the validity, but you can also guarantee that your keys won't
+stay valid in case you ever lose them. If you don't want to bother with
+refreshing your keys from time to time, just press enter here to continue.
+
+When prompted on whether the data is correct, doublecheck whether the data is
+really correct, and then enter `y` and press enter to accept the current
+values. `gpg` will continue with your identity information, which you should
+fill out with your real information. The comment field can be left empty, this
+is an optional field to add a comment to your identity, such as "School", or
+"Work keys". `gpg` will ask your confirmation one final time. Enter an `o`
+(it's not case sensitive) and press enter again. The final step before it will
+generate a key is to enter a passphrase. This is technically optional, but
+highly recommended. If anyone ever gets their hands on your private master key,
+they will need the passphrase in order to use it. Adding one is yet another
+layer against malicious use of your key.
+
+Once you've chosen a passphrase, it will generate they key and output some
+information about the key. Verify whether this information is correct one more
+time, and if it is, you can continue to the next step. If it is not, redo the
+whole PGP section of this post.
+
+Take note of the line starting with `pub`. It shows that the key is an
+`rsa4096` key, followed by a `/`, and then the key ID. You'll need this key ID
+throughout the rest of this post. For convenience, you can store this ID in
+a variable, and just refer to the variable when you need it's value again:
+
+```sh
+export KEYID=0x27F53A16486878C7
+```
+
+This post will use the `$KEYID` variable from now on, to make it easier to
+follow.
+
+### Creating a revocation certificate
+
+The revocation certificate can be used to invalidate your newly created key.
+You should store it seperately from the private master key, preferably printed
+on a sheet of paper. If you want to be able to easily read it back in, consider
+printing it as a QR code.
+
+To create the certificate, run the following:
+
+```txt
+gpg --gen-revoke $KEYID > $GNUPGHOME/revoke.txt
+```
+
+This will prompt you to specify a reason, for which you'll want to use `1`.
+This way you can easily revoke the key's validity if you ever lose it. If you
+want to revoke your keys in the future for any other reason, you can always
+generate a new revocation certificate for that specific purpose. You don't have
+to supply an additional description, so just hit enter. A revocation
+certificate will be written to `$GNUPGHOME/revoke.txt`.
+
+### Creating the subkeys
+
+Now that you have your master key and the ability to revoke it in case anything
+goes wrong in the future, it's time to create a couple of subkeys which can be
+stored on the Yubikey, and used in your daily life. We'll create seperate keys
+for _encryption_, _signing_ and _authentication_, and store each of them in
+their own dedicated slot on the Yubikey.
+
+To add subkeys to your master key, enter a GPG shell to edit your existing
+key with `gpg --expert --edit-key $KEYID`. The `--expert` is required to show
+all the options we're going to need. Once the GPG shell has started, run
+`addkey` to add a new key.
+
+Just like with the master key, a number of questions will be asked. Expiration
+for subkeys is generally not advised, as the subkeys will be considered invalid
+whenever the master key has expired. The key sizes for the subkeys can be left
+at 2048 as well, which is also the maximum size for keys for the older Yubikey
+models. The key type is different for all 3 subkeys.
+
+You will want to select type `4` (RSA (sign only)) for your signing key, type
+`6` (RSA (encrypt only)) for the encryption key, and type `8` (RSA (set your
+own capabilities)) for the authentication key. With the final key, it will ask
+you what capabilities you want to enable. The only capability you want it to
+have is *Authentication*.
+
+Once you've created the subkeys, you can check `gpg --list-secret-keys` to look
+at your newly created keys. You should have 1 `sec` key, which is the master
+key, and 3 `ssb` keys, which are the subkeys. One line should end with `[S]`,
+one with `[E]` and one with `[A]`. These denote the capabilities of the
+subkeys, _Sign_, _Encrypt_ and _Authenticate_, respectively.
+
+### Export the keys
+
+Now that you have your keys generated, you should export them, allowing you to
+easily import them in another environment in case you ever need to generate
+more keys, invalidate some keys, or extend the validity of the keys in case you
+set an expiry date. This can be done with the following commands:
+
+```txt
+gpg --armor --export-secret-keys $KEYID > masterkey.asc
+gpg --armor --export-secret-subkeys $KEYID > subkeys.asc
+```
+
+## Creating a backup USB
+
+For the backup of the private keys, I'm using an encrypted USB device. You can
+also opt to print the keys to paper, and retype them if you ever need them. Or
+print a QR code that you can scan. But for convenience sake, I went with a USB
+device. I encrypted it, and stored it in a safe and sealed location, so it's
+easy to detect unwanted attempted access.
+
+### Encrypting the USB
+
+For the encryption, I went with full device encryption using LUKS. You will
+need the `cryptsetup` utility to apply the encryption, and to unlock the drive.
+You can find out the device name from `dmesg` or `lsblk`. Once you know it,
+encrypt the drive with the `luksFormat` subcommand.
+
+{< admonition title="warning" >}
+Using the wrong name for the device can irrecoverably destroy data from another
+drive!
+{< / admonition >}
+
+```txt
+cryptsetup luksFormat /dev/sdb
+```
+
+It will prompt you whether you want to continue, and ask twice for a passphrase
+to ensure it is correct. Make sure you don't forget the passphrase, or you'll
+lose access to your backup keys.
+
+Once it has been encrypted, unlock the device.
+
+```txt
+cryptsetup luksOpen /dev/sdb crypt
+```
+
+This will open the device as `/dev/mapper/crypt`. Format it with your favourite
+filesystem. I used `ext4`.
+
+```txt
+mkfs.ext4 /dev/mapper/crypt
+```
+
+Once it has been formatted, you can mount it as a regular device.
+
+```txt
+mount /dev/mapper/crypt /mnt/usb
+```
+
+### Copying the keys
+
+Copying the keys is as straightforward as copying other files. You can use
+`$GNUPGHOME` to target the source directory.
+
+```txt
+cp -arv "$GNUPGHOME"/* /mnt/usb/.
+```
+
+Once the files are copied, you can unmount the drive, lock it and unplug the
+USB.
+
+```txt
+sync
+umount /mnt/usb
+cryptsetup luksClose crypt
+```
+
+Store the USB in a safe location, because these private keys can give someone
+full control of your identity.
+
+## Storing the private keys on the Yubikey
+
+The Yubikey has key slots for encryption, signing and authentication. These
+need to be set individually, which can be done using `gpg`. First, you need to
+select a key using the `key` command, then store it on the card using
+`keytocard` and select a slot to store it in, then finally deselect the key by
+using the `key` command again.
+
+```txt
+gpg --edit-key $KEYID
+
+gpg> key 1
+gpg> keytocard
+Your selection? 1
+gpg> key 1
+
+gpg> key 2
+gpg> keytocard
+Your selection? 2
+gpg> key 2
+
+gpg> key 3
+gpg> keytocard
+Your selection? 3
+
+gpg> save
+```
+
+You can verify whether the keys are available on the Yubikey now using `gpg
+--card-status`. It will show the key fingerprints for the `Signature key`,
+`Encryption key` and `Authentication key`.
+
+### Sharing your public key
+
+You can share your public keys in many ways. Mine is hosted link:/pubkey.txt[on
+my own site], for instance. There are also https://sks-keyservers.net/[public
+keyservers] on which you can upload your keys. `gpg` has the `--send-keys` and
+`--recv-keys` switches to interact with these public keyservers. For ease of
+use, I would recommend uploading them to a public keyserver, so that other
+people can easily import it. For instance, my key can be imported using `gpg`:
+
+```txt
+gpg --recv-keys 0x7A6AC285E2D98827
+```
+
+## Clean up
+
+The keys are on the Yubikey, and you probably do not want to leave traces on
+your local system of these new keys, so you should clean up the `$GNUPGHOME`
+directory. There's a utility for securely removing a directory with all its
+contents, called `secure-delete`, which provides the `srm` program. You can use
+it just like the regular `rm` on the temporary directory.
+
+```txt
+srm -r "$GNUPGHOME"
+```
+
+You can also `unset` the `$GNUPGHOME` variable at this point, so `gpg` will use
+it's default configuration again.
+
+```txt
+unset GNUPGHOME
+```
+
+## Configure GPG
+
+Finally, you have your keys on the Yubikey and the traces that might have been
+left on your device are wiped clean. Now you should configure `gpg` for regular
+use as well, however, this is completely optional. All this configuration does
+is ensure you have good defaults for the current day and age.
+
+```conf
+auto-key-locate keyserver
+keyserver hkps://hkps.pool.sks-keyservers.net
+keyserver-options no-honor-keyserver-url
+personal-cipher-preferences AES256 AES192 AES CAST5
+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-cipher-algo AES256
+s2k-digest-algo SHA512
+charset utf-8
+fixed-list-mode
+no-comments
+no-emit-version
+keyid-format 0xlong
+list-options show-uid-validity
+verify-options show-uid-validity
+with-fingerprint
+use-agent
+require-cross-certification
+```
+
+## Conclusion
+
+You now have PGP keys available on your Yubikey. These keys are only available
+to your system if the Yubikey is inserted, and the user PIN is given. You can
+use these keys for authentication, signing and encrypting/decrypting messages.
+In a future post, I'll detail how to set up a number of services to use these
+keys as well.