Table of Contents
Setting Up GPG Keys from Scratch
Disclaimer: This isn’t really supposed to be a comprehensive guide on how you should set up GPG, it’s more a record of what I did and why. This post will inevitably become outdated in the future so please use good judgement when it comes to your security.
Now that I’m self-hosting mail and moving off of ProtonMail, I figured I need to actually properly figure out GPG so I can send and receive encrypted emails. It will also be essential as I get further involved in free and open source software development since GPG is commonly used to sign software releases, among other things.
GPG is notorious for being quite complicated and not user-friendly. To assist in my GPG adventures, I enlisted the help of the Internet; mainly the Arch wiki.
I previously played around with GPG so I could use it for encrypting local backups and for signing git commits. I wasn’t using it seriously in any other respect so I began by
rm -rfing my
~/.gnupg directory for a fresh start. I also set the
GNUPGHOME environment variable to a directory on the SD card which I use specifically to store key data. On this SD card are key files, SSH keys, and now GPG keys all under LUKS encryption (don’t worry, I keep many copies of this SD card on other cards, USB sticks, and hard drives). Having a separate portable medium for my keys makes it so that I only have to worry about updating what’s on the card instead of what’s on all of the machines on which I am using GPG. It’s also technically a lot easier to hide or destroy, but I don’t see myself realistically needing to do that.
Generating the Master Key
Generating the master key is pretty straightforward.
gpg --full-gen-key --expert$
--expert is required because I wanted to use Elliptic Curve Cryptography (
ed25519 keys in particular) instead of RSA since ECC keys are smaller for a similar level of security. From the article linked above: “a 256-bit elliptic curve public key should provide comparable security to a 3072-bit RSA public key”. This will make typing in the key a lot easier and less error-prone should I have to restore it from paper backups. It’s also fewer bits to send over the Internet when sharing my public keys.
Generating a Revocation Certificate
It’s very important to have a revocation certificate since it’s what one publishes if their key is ever compromised or otherwise needs to be revoked. It’s essentially a way for one to tell the world “under no circumstances should you use or trust this key.” Unlike with subkeys, revoking a master key is much more significant since, once that becomes compromised or lost, one has to start again from scratch.
gpg --gen-revoke --armor --output=revocation-certificate.asc <user-id>$
<user-id> in this case is the email I specified when generating my key:
Typically, one shouldn’t be using their master key for every-day use. That’s because one’s master key is used for signing others’ keys, issuing new keys, and it’s the ultimate representation of one’s GPG identity. Instead, one should use subkeys as it’s far easier to revoke them and issue new ones in the case that they become compromised.
I generated one subkey specifically for signing and one subkey specifically for encryption:
gpg --edit-key --expert firstname.lastname@example.org $ >addkey
I also set a one month expiry on both of those subkeys. While I think having an expiring master key is overkill for my uses and would be too much hassle, having subkeys expire is useful in the case that access to those subkeys is lost. This allows me to be less neurotic about backing up my subkeys compared to backing up my master key.
I chose a length of one month because it will keep me coming back to GPG regularly. This way, I can both make sure that my master key backups have not become corrupted without my knowledge and that I keep my GPG skills honed. It also gets me in the habit of doing monthly maintenance on my keyring.
Going Backup Crazy
To make sure that my master key and revocation certificate stay as private as possible and to minimize the risk of me ever losing access to them, I went a little bit crazy with the number of backup copies I made.
It’s extremely important to have physical copies of both because digital media can fail over time in ways that are hard to detect until one needs to access the data. I printed my revocation certificate directly since it’s just a short bit of ascii text and I printed out my master key using
paperkey. Both of these pieces of paper went into my fire- and water-proof storage bag.
gpg --export-secret-key email@example.com > privkey.gpg $ paperkey --secret-key privkey.gpg --output printed.txt $ lpr printed.txt $ rm privkey.gpg printed.txt$
I also made several digital copies of my private key. First, I exported my master key using:
gpg --export-secret-keys --armor firstname.lastname@example.org > master.asc$
Then, using GPG’s symmetric encryption capabilities, I encrypted both it and my revocation certificate using a completely new, randomly generated passphrase:
gpg -c master.asc $ gpg -c revocation-certificate.asc $ rm master.asc revocation-certificate.asc$
I then put both of the new encrypted files:
revocation-certificate.asc.gpg onto two separate CDs—one went into my fireproof bag—and onto a floppy disk which also went into my fireproof bag. As soon as I have a free USB key, I’ll be making a copy on that too.
Uploading My Keys to a Keyserver
Using a keyserver allows for both easier access to my public keys for others as well as convenient offsite storage for the public part of my master key which is required to restore the private part of my master key using
paperkey. A while back, an attack on the SKS keyserver network was discovered which caused many to become apprehensive about using keyservers. A solution proposed in the linked article was to use keys.openpgp.org which is a new keyserver designed to mitigate the issues with the old keyservers. Following the given instructions, I uploaded my public keys so others should now be able to find me by searching for my email. Any time I need to use my master key (e.g. to sign another’s key or renew my subkeys), I can re-sync my public keys with the keyserver so they always stay up to date in others’ keyrings.
Configuring GPG and GPG-Agent
This is pretty simple and straightforward. Taking a few notes from the Arch wiki and setting options that I wanted to avoid having to type each time I ran
gpg, I came up with the following configuration files:
gpg.conf -------- keyserver hkps://keys.openpgp.org keyid-format long with-fingerprint with-subkey-fingerprint personal-digest-preferences SHA512 cert-digest-algo SHA512 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
gpg-agent.conf -------------- # Cache for a day max-cache-ttl 86400 default-cache-ttl 86400 # Use curses-based pinentry program pinentry-program /usr/bin/pinentry-curses
Deleting My Master Key
All of that backing up and making offline copies of my master key is so that I can do daily tasks with just my subkeys. To make this make sense, I have to delete my master key out of my keyring so it only exists offline until I need to use it. Since GnuPGv2.1, this is fairly straightforward:
gpg --list-keys --with-keygrip $ rm /media/jbauer/keys/gpg/private-keys-v1.d/<keygrip>.key$
After decrypting it from one of my backups, I can then later restore this key (which I’ll have to do at least once a month) by re-importing it with:
gpg --import master.asc$
Without a doubt, using GPG is quite complicated. There are a variety of decisions that one can make depending on their desired level of security or anonymity which can be overwhelming if one doesn’t have much experience. I’ve spent probably 3 or 4 hours making sure that my processes are sound and making sure I’m doing everything right. To be honest, since I’m relatively new to using GPG seriously, I won’t be 100% sure I’m doing things right until I can experience using it in the real world.
This is my twenty-second post for the #100DaysToOffload challenge. You can learn more about this challenge over at https://100daystooffload.com.