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?
- Convert A PGP Key To An SSH Key
- Locating A Public Key
- Updating Your Keyring
- Signing A Public Key
- Extending An Expiration Date
- Backing Up A GnuPG Directory
Today, the Linux kernel development cycle is solely (for now) an email based work-flow involving pulling changes from over ~300 different repositories.  These changes will eventually make their way into Linus' main tree (the mainline) for the final approval before being distributed to the masses.
|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 firstname.lastname@example.org
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 , 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.
|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.
- 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
- To find someone's PGP key,
git grepfor the key in the repository:
$ git grep -l torvalds *.asc
- Then import the key into our keyring:
$ gpg --import keys/79BE3E4300411886.asc
- Alternatively: we could import all keys currently in the repository:
$ gpg --import keys/*.asc
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] email@example.com
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
$ cat ~/.config/systemd/user/korg-refresh-keys.service
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 firstname.lastname@example.org
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.
|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.
|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.
|Signs a public key with your secret certification key. This is a
shortcut version of the subcommand "sign" from
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 email@example.com 1y
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
indicating that both the public and the secret key material are
available for your main certification key.
Once you have finished making your changes, we need to import these
changes back into our everyday working
$ gpg --export | gpg --homedir ~/.gnupg --import
$ unset GNUPGHOME
$ gpg --list-secret-keys
You should now see
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
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.