My PGP Cheat Sheet

The PGP commands I use, but not enough to remember.

published: 

I use gpg about as often as tar which is just enough time to forget how to use it.

What lies below are my (a Linux kernel contributor) notes on some of the less used commands to keep your gpg keys safe and your copy of the Linux Web of Trust up to date.

Please feel free to contact me if anything you read below is wrong, out of date, or find something I should expand on. :)

Helpful Jump To Points:

Why PGP?

Today, the Linux kernel development cycle is solely (for now) an email based work-flow involving pulling changes from over ~300 different repositories. [1] These changes will eventually make their way into Linus' main tree (the mainline) for the final approval before being distributed to the masses.

[1]Not every repository needs to be pulled before each release - though the linux-next repository, the repository subsystem maintainers use to resolve merge conflicts before they reach Linus, tracks around 300.

With the existence of phishing, spoofing and other social-engineering attacks, any one of these pull requests could conceivably bring malicious code via a spoofed email, fooling either Linus or any one of the subsystem maintainers.

After the widespread credential stealing attack that compromised much of the core kernel.org infrastructure in 2011, the decision was made to develop a PGP based Web of Trust to give developers a way to independently verify other repositories without a central authority.

Now days, pull requests must have a signed tag from a PGP key the maintainer trusts not only to validate the pull request, but to attest to the changes being made. Like a chain of custody.

Convert A PGP Key To An SSH Key

Each PGP key can have one or more roles; Signing, Encryption, Authentication or Certification. One "neat" feature about authentication keys is they can be used as an OpenSSH key, allowing you to store your SSH and PGP keys together on the same NitroKey.

Any time you need to give out your public SSH key, just use this command:

$ gpg --export-ssh-key hello@bryanbrattlof.com
ssh-rsa AAAAB3NzaC1yc2E ...

Linode has a good writup on how to get started using your PGP key with SSH.

Locating A Public Key

Around June of 2019 [2], the public SKS Keyserver network used to publish public PGP keys was attacked in a way that could not be easily fixed. The attacker(s) attached thousands of valid but useless signatures to well known PGP keys to bloat the complexity of the Web of Trust graph and render gpg unusable for anyone unfortunate enough to download a "poisoned" key.

[2]This was a known problem for more than a decade.

As a work-around, the Linux community published a repository of all the well known contributers to the kernel called pgpkeys.git, that we can use to send and receive updates to our PGP keys to the kernel community.

  1. Before we can find a key, we need to clone the kernel's PGP keyring repository:
$ git clone https://git.kernel.org/pub/scm/docs/kernel/pgpkeys.git korg-keys
  1. To find someone's PGP key, git grep for the key in the repository:
$ git grep -l torvalds *.asc
keys/79BE3E4300411886.asc
  1. Then import the key into our keyring:
$ gpg --import keys/79BE3E4300411886.asc
  1. Alternatively: we could import all keys currently in the repository:
$ gpg --import keys/*.asc

Done!

With your key imported, we will need a way to update these keys from the PGP repository. See the Updating Your Keyring section below.

Updating Your Keyring

After the public SKS keyserver network was abandoned and the Linux kernel developer's PGP keyring repository was created, any update to a kernel developer's PGP key should be uploaded to the repository so they can be shared with the community.

To submit changes to your keys, use this command to email your updates to the mailing list:

$ gpg -a --export [Email] | mail -s [Email] keys@linux.kernel.org

To download updates from the keyring repository, a helpful script was added, allowing us to download any new changes using cron, systemd, or invoking the script manually.

I prefer to let systemd run the script:

$ cat ~/.config/systemd/user/korg-refresh-keys.timer
[Timer]
OnCalendar=daily
Persistent=yes

[Install]
WantedBy=sockets.target
$ cat ~/.config/systemd/user/korg-refresh-keys.service
[Service]
ExecStart=%h/bin/korg-refresh-keys -q
Type=oneshot

So I can see how the script is doing at any time by running:

$ journalctl --user -fu korg-refresh-keys

Signing A Public Key

Once you feel confident signing someone's key or UID(s) and attesting to the validity of their PGP key, you can sign it with the following command:

$ gpg --ask-cert-level --ask-cert-expire --sign-key someone@example.com

Each situation is different, and everyone (and each community) has their own methods for signing someone's key. This is only the default arguments I use, and adapt to the situation.

--ask-cert-level
 Prompt for a certification level allowing you to specify how confident you are about this signature. Useful to signal the difference between the random person you met at a conference versus your workmate.
--ask-cert-expire
 Prompt for an expiration time, allowing your signature to expire after a set amount of time. I like to put a expiration date on my signatures when possible if only to stop an old email address having a valid signature from me.
--sign-key <name>
 Signs a public key with your secret certification key. This is a shortcut version of the subcommand "sign" from --edit-key.

If you're like me and store your certification key offline in an encrypted USB drive, (something I strongly encourage) this process will be a little more complicated.

Don't forget to update your backup after you finish.

Extending An Expiration Date

By default, master certification keys have an expiration date set two years from the date of their creation. This is for security reasons and to let obsolete keys disappear from the Web of Trust.

To add one year (from the current date) to the expiration, run:

$ gpg --quick-set expire hello@bryanbrattlof.com 1y

Make sure to backup your GnuPG directory as well as email the kernel developer's keyring mailing list to let everyone know about the changes you have made.

Backing Up A GnuPG Directory

Now that we live squarely in the hyper-connected information age, the more sensitive data we can store, encrypted and offline, the better. This includes keeping all the secret key material used in our PGP keys off our working computers.

How much effort you spend backing up your private keys is ultimately your decision. My goal is to have a good story to tell the mailing lists explaining how I lost control of my keys. I feel comfortable having two LUKS encrypted USB drives and a paperkey backup, storing all of my PGP keys, and allowing me to restore my Nitrokey if that device happens to die.

If you are like me and prefer to keep your main certification key safely stored in an encrypted drive and off our working computer, you will need to mount your encrypted device first:

$ mkdir /media/device/gnupg-backup
$ cryptsetup luksOpen [DEVICE] gnupg-backup-enc
$ mount /dev/mapper/gnupg-backup-enc /media/device/gnupg-backup

Then we can tell gpg to use it:

$ export GNUPGHOME=/media/device/gnupg-backup
$ gpg --list-secret-keys

You should now see that sec# has been replaced with sec indicating that both the public and the secret key material are available for your main certification key.

Now is a good time to make changes that require our main key like Extending An Expiration Date, Signing A Public Key or running commands like fsck on the decrypted volume.

Once you have finished making your changes, we need to import these changes back into our everyday working .gnupg directory:

$ gpg --export | gpg --homedir ~/.gnupg --import
$ unset GNUPGHOME
$ gpg --list-secret-keys

You should now see sec# and ssb> have returned.

Finally, unmount and close our encrypted volume, and return our USB drive to its safe place.

$ unmount /media/device/gnupg-backup
$ cryptsetup luksClose gnupg-backup-enc
$ rmdir /media/device/gnupg-backup

Wrapping Up

I will say gpg is not the easiest tool to use. After 30 years of development, the time and effort needed to maintain the Web of Trust seems to be more than many are willing to endure.

As difficult as it is, gpg is a great open source tool, helping developers from all around the world regardless timezone, language, or access to git-forges like Github the opportunity to work on one of the most widely used software projects in the world.

I hope these notes helped you in some way. If you read anything that needs to be updated or you feel like I should expand on something, please feel free to write me an email.