see all posts

Getting Started with PGP and GPG

A setup guide for GPG newcomers

PGP can be somewhat complicated. As such, there aren't very many guides for newcomers. Many which do exist are either outdated or incomplete. In this post, I'll do my best to sum up what I've learned about setup for these very confusing acronyms over the last eight days.

A Brief Introduction

PGP (Pretty Good Privacy) was developed by Phil Zimmerman in 1991. PGP is an asymmetric encryption algorithm, which just means that the encryption key is not the same as the decryption key. An example of a symmetric encryption algorithm is AES, which uses the same key for both.

AES is a powerful algorithm, but it's really only good for talking to yourself. If you want to encrypt data for other people using AES, you need a way to securely transmit the key. This is where asymmetric encryption is useful!

With PGP, users have both a public key as well as a private key. The private key is the decryption key which decrypts messages which were encrypted with the public key. If Bob wants to send a message to Alice, Bob uses Alice's public PGP key to encrypt the message. Bob can then rest assured that only the person who possesses Alice's decryption key is able to read the message.

(If you're not sold on the technical stuff, Keybase is a really great way utilize encryption without all the complexity. I'm johnnyRose on Keybase; let's chat!)

Installing GPG

So without further ado, let's get started. The first thing we will want to do is install GPG, which stands for GNU Privacy Guard (yes, the acronyms are ridiculous). If you're running Linux or macOS, you might already have it installed: check with gpg in your terminal. Either way, you'll want to have it updated. At the time of writing, 2.2.2 was the most recent version. Check your package manager's instructions for specifics. For Windows users, head over to https://www.gnupg.org/download/mirrors.html and pick a mirror close to you, then navigate to binary and select the most recent version of gnupg-w32. Unfortunately, this page is a mess, so it looks intimidating at first. Here is version 2.2.2 for Windows from Japan's mirror. Make sure the output of gpg --version is 2.2.2 and you should be ready to roll.

Generating a Keypair

Let's jump right in. First, you'll want to run gpg --full-generate-key:

Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
Your selection? 1

Select key type 1 for RSA and RSA. GPG will then ask you how large you want your key to be. For security, you'll want the largest key you can get. If you're wanting to add these keys to a YubiKey, only the YubiKey 4 will support 4096 bits. You'll have to stick with 2048 for any other YubiKey, for now. I'm going to move forward with 4096, but keep that in mind. If you aren't planning on using a YubiKey, or own a YubiKey 4, use 4096.

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 4096

Next, you'll add an expiration date. This is important in case you lose access to your key. You can always change the expiration date of your keys, even after it expires, so don't let this part stress you out.

Please specify how long the key should be valid.
0 = key does not expire
<n>  = key expires in n days
<n>w = key expires in n weeks
<n>m = key expires in n months
<n>y = key expires in n years
Key is valid for? (0) 1y

I'm expiring my key after one year. You can do whatever feels appropriate. Confirm your expiration date and let's move on.

Next you'll want to enter your full name (first and last) and email address. This will allow other people to locate your public key so they can send you encrypted messages. It will also ask you for a comment, which you can populate if you desire. Fill in the information and type O (for Okay) to continue.

Real name: Harry Potter
Email address: hpotter1@hogwarts.edu
Comment:
You selected this USER-ID:
    "Harry Potter <hpotter1@hogwarts.edu>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

Finally, you'll be prompted for a passcode. Make it a strong one, because this passcode is the final layer of protection if your secret key is lost or stolen. There is also no way to reset a forgotten password, so store it somewhere secure if you need to.

After you input your password, you'll see this:

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.

Seems straightforward enough. Make sure you move your mouse and slam some keys while this is happening to give the PRNG some good data to work with. After this is finished, you'll have your master public/private keypair! Huzzah!

gpg: key 78AF9058B9FE04A5 marked as ultimately trusted
gpg: revocation certificate stored as '/Users/harry/.gnupg/openpgp-revocs.d/4E2DC9B7D2079E64258A0F6678AF9058B9FE04A5.rev'
public and secret key created and signed.
pub   rsa4096 2017-11-18 [SC] [expires: 2018-11-18]
      4E2DC9B7D2079E64258A0F6678AF9058B9FE04A5
uid                      Harry Potter <hpotter1@hogwarts.edu>
sub   rsa4096 2017-11-18 [E] [expires: 2018-11-18]

Updating Hash Preferences

Let's strengthen the hash preferences to prefer stronger algorithms by running gpg --edit-key hpotter1@hogwarts.edu. This should pull up the gpg> prompt and allow us to modify the key we just created. Type showpref to view your current preferences, and enter setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed to update them. Confirm, enter your passcode, and enter showpref again to view your changes. Exit this prompt with save.

Adding a Signing Subkey

An encryption subkey was already generated as part of the master key generation. We are going to add new signing and authentication subkeys as well. But first: what is a subkey?

A subkey can be thought of as a child of your master key. It is still eternally bound to the master key, but if it gets lost or stolen, you only need to revoke the subkey as opposed to revoking the entire identity associated with the master key. This allows users to maintain their web of trust should something happen to one of the subkeys.

Put simply: subkeys are much safer to use in other devices. Your master secret key should never be transferred to another device (with the exception of a flash drive - more on this later).

So, let's generate these subkeys. Run gpg --edit-key hpotter1@hogwarts.edu and type addkey. Select key 4 (RSA, sign only) to create a new secret subkey.

gpg --edit-key hpotter1@hogwarts.edu
gpg (GnuPG) 2.2.2; Copyright (C) 2017 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec  rsa4096/78AF9058B9FE04A5
     created: 2017-11-18  expires: 2018-11-18  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/87A4AD57E3E92028
     created: 2017-11-18  expires: 2018-11-18  usage: E
[ultimate] (1). Harry Potter <hpotter1@hogwarts.edu>
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 4

Next, select a size (remember any restrictions which may apply to YubiKeys) and expiration date again. I suggest using the same expiration date as your master key for simplicity, but that's up to you.

Confirm everything, enter the passphrase, and help the program gain some entropy. When it's finished, type save to save your new signing key to your master key. This will update the public key to reference the public part of a new valid signing key.

Optional: Adding an SSH Authentication Subkey

Now it's time to generate the authentication key for SSH. You can skip this part if you don't need it.

Type gpg --expert --edit-key hpotter1@hogwarts.edu. Notice the addition of the " --expert" flag. This gives us more flexibility. Type addkey again and select option 8 (RSA, set your own capabilities).

gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
Your selection? 8

The default capabilities are Sign and Encrypt. Enter s to toggle the Sign value, and e to toggle the Encrypt value. Finally, enter a to turn on Authenticate. After that, you should see this:

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Authenticate
(S) Toggle the sign capability
(E) Toggle the encrypt capability
(A) Toggle the authenticate capability
(Q) Finished
Your selection? q

Enter q to quit, enter the desired key size and expiration date, and confirm. Enter your passcode and give the program some entropy. When it's all done, you'll have a nice summary view of your current keys:

sec  rsa4096/78AF9058B9FE04A5
     created: 2017-11-18  expires: 2018-11-18  usage: SC
     trust: ultimate      validity: ultimate
ssb  rsa4096/87A4AD57E3E92028
     created: 2017-11-18  expires: 2018-11-18  usage: E
ssb  rsa4096/4FA2918BB804FA1B
     created: 2017-11-18  expires: 2018-11-18  usage: S
ssb  rsa4096/C2522E4BDAC835A1
     created: 2017-11-18  expires: 2018-11-18  usage: A
[ultimate] (1). Harry Potter <hpotter1@hogwarts.edu>

Enter save to exit and save your changes.

Generating a Revocation Certificate

If you closely read the confirmation after initially creating your master key, you noticed that it created something called a "revocation certificate". This file allows you to revoke your public key if your private key becomes compromised. Well, if you read that revocation certificate it referenced, you'll see that it's better to create a new one ourselves to specify a reason for the revocation. So, let's do that next. Enter gpg --output revocation-certificate.asc --gen-revoke hpotter1@hogwarts.edu and follow the prompts.

gpg --output revocation-certificate.asc --gen-revoke hpotter1@hogwarts.edu
sec  rsa4096/78AF9058B9FE04A5 2017-11-18 Harry Potter <hpotter1@hogwarts.edu>
Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 1
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key has been compromised
(No description given)
Is this okay? (y/N) y
ASCII armored output forced.
Revocation certificate created.
Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable. It is smart to print this certificate and store it away, just in case your media become unreadable.  But have some caution:  The print system of your machine might store the data and make it available to others!

Heed GPG's warning: this file is just as important as your secret key, and should be stored somewhere very safe, separately from your master keypair. Example: master keypair stored in your home safe, revocation certificate stored in your safety deposit box.

Export Keys to File System

Now that you've created your keypair, let's export it so we can store it somewhere safely.

gpg --export-secret-keys --armor hpotter1@hogwarts.com > private.asc
gpg --export --armor hpotter1@hogwarts.com > public.asc

Removing your Master Secret Key

A good rule of thumb: it doesn't matter what kind of machine you're using or how portable it is - your master secret key should not be on your device. If your device is stolen, hacked, infected, or otherwise compromised, you would be forced to consider your private key compromised as well. This would mean one of two things:

  1. You generated a revocation certificate and stored it somewhere safe. Great. Now, revoke your public key, lose your web of trust, and essentially create a new identity for yourself.
  2. You did not generate or you do not have access to a revocation certificate. Now there is no way to tell the world that your key no longer belongs to you, and you're in big trouble.

Neither of those are great options! If you used subkeys, though, the solution would be as simple as revoking your subkey and re-publishing your key. Easy! You still have your web of trust and you are still known by the same identity. Crisis averted.

So, let's take care of that. First, export your subkeys with gpg --export-secret-subkeys hpotter1@hogwarts.edu > subkeys.

Next, you'll delete your secret key from the GPG keyring. Remember, we already backed this key up to a file, so this isn't as dangerous as it could be. Remove your secret key with gpg --delete-secret-keys hpotter1@hogwarts.edu. Confirm several times if you're actually sure.

Finally, re-import your subkeys with gpg --import subkeys. Confirm with gpg --list-secret-keys. Your output should be similar to the one below:

sec#  rsa4096 2017-11-18 [SC] [expires: 2018-11-18]
4E2DC9B7D2079E64258A0F6678AF9058B9FE04A5
uid           [ultimate] Harry Potter <hpotter1@hogwarts.edu>
ssb   rsa4096 2017-11-18 [E] [expires: 2018-11-18]
ssb   rsa4096 2017-11-18 [S] [expires: 2018-11-18]
ssb   rsa4096 2017-11-18 [A] [expires: 2018-11-18]

The pound sign next to sec means that the key is not stored on this keyring.

Securely delete the subkeys file when you're done with it. Phew! We are almost done!

Final Steps

This is probably the most important part, so be careful: you need to find a way to securely store your master keys (public and private) and revocation certificate. This can be on separate flash drives, printed paper, whatever - it just needs to be secure. Ideally, I'd recommend storing them on separate, encrypted flash drives with a sealed paper printout as a backup. If you need to write down the password for the master key, hand-write it with pen, don't print it (in case your printer keeps logs). When everything is securely stored to your satisfaction, make sure you securely delete any keys or revocation certificates left from the export process above.


Notes

If you're using Keybase and you don't already have a PGP key associated, you can add it with keybase pgp select. If you already have a PGP key associated and want to use your new one instead, register your new one with keybase pgp select --multi and do what you want with the old key. Finally, running keybase pgp update will update the PGP key associated with your account when you make changes (adding or revoking subkeys, adding a photo, etc).

Besides Keybase, another great way of making your public key known and accessible is to upload it to a keyserver. There are many to choose from, but the MIT PGP Public Key Server is probably the most popular. You can use the GPG client to do this with gpg --send-keys or you can simply submit your public key through their web interface. They both do the same thing. A word of caution: once you upload your public key, there is no going back. You cannot remove it from the keyservers. Many of them will synchronize with each other, so by adding your key you are submitting it forever. You'll be able to update it after revocations or updates, though. Definitely make sure you are 100% ready for the world to start using your public key before you upload it.

My public key can be found here on Keybase or here on MIT's keyserver. Fingerprint: 3973E24CA76E7EB26722F8EB6EDEFFCCB32303F6

If you're storing your subkeys on a YubiKey (highly recommended) you may also be interested in reading about yubitouch.sh. This is a script you can run which changes the touch request settings on your YubiKey. This can set your YubiKey to require a touch event to restrict the use of private keys.

"YubiKey 4 introduces a new touch feature that allows to protect the use of the private keys with an additional layer. When this functionality is enabled, the result of a cryptographic operation involving a private key (signature, decryption or authentication) is released only if the correct user PIN is provided and the YubiKey touch sensor is triggered. This request of user presence ensures that no malware can issue commands to the YubiKey without the user noticing."

Read more here, under "YubiKey 4 touch".

I hope this has been useful. If nothing else, it will be handy for me to reference. Leave me a note (encrypted maybe?) and share your experience!

More Resources