From d274004b213d846afcde7ff4063bca7845dcc41b Mon Sep 17 00:00:00 2001
From: Patrick Spek <p.spek@tyil.nl>
Date: Fri, 7 Sep 2018 15:02:01 +0200
Subject: Rename "Securing Your Workstation" to "Setting up PGP with a Yubikey"

---
 .../2018-09-04-setting-up-pgp-with-a-yubikey.adoc  | 458 +++++++++++++++++++++
 1 file changed, 458 insertions(+)
 create mode 100644 _posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc

(limited to '_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc')

diff --git a/_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc b/_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc
new file mode 100644
index 0000000..5dd279a
--- /dev/null
+++ b/_posts/2018-09-04-setting-up-pgp-with-a-yubikey.adoc
@@ -0,0 +1,458 @@
+---
+date: 2018-09-04
+tags: security yubikey pgp gpg
+description: >
+  An introduction to decent security using the Yubikey as your physical
+  security card.
+---
+= Setting up PGP with a Yubikey
+:toc: preamble
+
+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.
+
+[NOTE]
+====
+I am using the Yubikey 4. If you're using another version, some steps may
+differ.
+====
+
+== 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 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:
+
+[source]
+----
+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:
+
+[source]
+----
+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`:
+
+[source]
+----
+gpg/card> 1
+----
+
+Once this is done, you can quit the `passwd` submenu using `q`:
+
+[source]
+----
+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`:
+
+[source]
+----
+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:
+
+[source]
+----
+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:
+
+[source,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:
+
+[source,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`:
+
+[source]
+----
+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:
+
+[source,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:
+
+[source]
+----
+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:
+
+[source,sh]
+----
+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.
+
+[WARNING]
+====
+Using the wrong name for the device can irrecoverably destroy data from another
+drive!
+====
+
+[source,sh]
+----
+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.
+
+[source,sh]
+----
+cryptsetup luksOpen /dev/sdb crypt
+----
+
+This will open the device as `/dev/mapper/crypt`. Format it with your favourite
+filesystem. I used `ext4`.
+
+[source,sh]
+----
+mkfs.ext4 /dev/mapper/crypt
+----
+
+Once it has been formatted, you can mount it as a regular device.
+
+[source,sh]
+----
+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.
+
+[source,sh]
+----
+cp -arv "$GNUPGHOME"/* /mnt/usb/.
+----
+
+Once the files are copied, you can unmount the drive, lock it and unplug the
+USB.
+
+[source,sh]
+----
+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 finally deselect the key by using the `key` command again.
+
+[source]
+----
+gpg --edit-key $KEYID
+
+> key 1
+> keytocard
+> key 1
+
+> key 2
+> keytocard
+> key 2
+
+> key 3
+> keytocard
+
+> 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`:
+
+[source]
+----
+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.
+
+[source,sh]
+----
+srm -r "$GNUPGHOME"
+----
+
+You can also `unset` the `$GNUPGHOME` variable at this point, so `gpg` will use
+it's default configuration again.
+
+[source,sh]
+----
+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.
+
+[source]
+----
+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.
-- 
cgit v1.1

