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.
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
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: firstname.lastname@example.org Comment: You selected this USER-ID: "Harry Potter <email@example.com>" 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 <firstname.lastname@example.org> 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 email@example.com.
This should pull up the
gpg> prompt and allow us to modify the key we just created. Type
showpref to view your current preferences,
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
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 firstname.lastname@example.org and type
addkey. Select key 4 (RSA, sign only) to create a new secret subkey.
gpg --edit-key email@example.com 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 <firstname.lastname@example.org> 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.
gpg --expert --edit-key email@example.com. Notice the addition of the " --expert" flag. This gives us more flexibility.
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.
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
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 <firstname.lastname@example.org>
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 email@example.com and follow the prompts.
gpg --output revocation-certificate.asc --gen-revoke firstname.lastname@example.org sec rsa4096/78AF9058B9FE04A5 2017-11-18 Harry Potter <email@example.com> 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 firstname.lastname@example.org > private.asc gpg --export --armor email@example.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:
- 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.
- 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 firstname.lastname@example.org > 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 email@example.com. 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 <firstname.lastname@example.org> 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!
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.
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.
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.
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!