Back to Roots

Managing GPG keys

#gpg #security #notes

I never remember how to deal with all of those, so I write an article for myself :) To choose options and method, I followed several articles on the web:

And a few others (french):

Ensuring a clean setup

I consider not having an existing key. If so first kill gpg-agent and move the keyring.

$ gpgconf --kill gpg-agent
$ unset GPG_AGENT_INFO
# also check there is no other security related process running
# mostly from any desktop environment or web browsers or what's not
$ tar -cf previous-keyring.tar ~/path/to/current-gnupg-home

Set the new GnuPGg home (I prefer XDG standard directories)

$ export GNUPGHOME=$XDG_CONFIG_DIR/gnupg
$ mkdir -p $GNUPGHOME
$ chmod 700 $GNUPGHOME
$ gpg -k

GnuPG config should be ok by default so no need to edit it.

For the sake of examples, I’ll use the following environment variables and/or values for some specific purpose:

Create the keys the hard way

Master key

The goal will be to have a detached master key, not using it but for managing keys (no sign, no crypt, no auth) so we can choose the algo we want without worrying about compatibility for recipients.

To create only a certifying master key, you must enter the expert mode (not much more than the classic mode):

$ gpg --expert --full-generate-key
# * choose ECC (set your own capabilities)
# * keep Certifiate only (remove Sign) then Quit
# * choose the 25519 Curve
# * I keep my master key valid for 2 years (2y)
#
# * choose an identity (name then email), no comment
# * choose a very strong passphrase

GnuPG creates a revocation certificate that wont be used. It’s better to generate one when needed, and to delete the one that was created.

Elliptic Curve subkeys

We will create elliptic curve (EC) because now they seem to be the default. So lets create subkeys for each role (sign, crypt and auth), editing the key from its fingerprint (printed when then key has been generated, under the pub part, can use only the 4 bytes (8 hexa characters):

$ gpg --edit-key --expert $FINGERPRINT
gpg> addkey
# select ECC (sign only)
# then the type Curve 25519
# and a one year validity (1y), less than the master key

Do the same for ECC (encrypt only), and ECC (set your own capabilities, then choose authenticate only).

So we have a master key (sec) with 3 elliptic curve subkeys:

Let’s save to be sure they are stored.

gpg> save

Adding another identity

If I want to add another email to my master key:

$ gpg --edit-key --expert $FINGERPRINT
gpg> adduid
# then set one primary first selecting it (let's say it's the second one we just
# created)
gpg> uid 2
gpg> primary
gpg> save

The primary identity is shown with a dot (.) after the identity number.

Publish keys

Using keys.openpgp.org:

$ grep keyserver $GNUPGHOME/gpg.conf
keyserver hkps://keys.openpgp.org
$ gpg --send-keys $FINGERPRINT

Backup keys

Create a temporary folder:

$ mkdir $HOME/gpg-backup
$ chmod 700 $HOME/gpg-backup
$ cd $HOME/gpg-backup

Then generate the backup of private/public keys with master key:

$ gpg -o identity-backup.gpg --export-secret-keys example@freedom.email

When we will have people using our keys and us using their keys, we will import their public keys and set a trust level on them, so it’s good to save those when they change too:

$ pwd
/home/me/gpg-backup
$ gpg -o public-keys.gpg --export
$ gpg --export-ownertrust > ownertrust.txt

Now it’s good to move that backup to a secure place, or better, two of them. Of course do not put the backup on an encrypted usbkey that’s encrypted with this key…

Backup on a physical paper

It’s said making a paper backup of the private key is a good idea:

$ paperkey --secret-key backup.gpg > paperkey.txt

To restore, scanning the paper with OCR will be needed, and use again:

$ paperkey --pubring public-keys.gpg --secrets paperkey.txt --output identity-backup.gpg

Restore backup

# if needed:
$ mkdir $GNUPGHOME; chmod 700 $GNUPGHOME
# then from the backup directory:
$ gpg --import identity-backup.gpg
$ gpg --import public-keys.gpg
$ gpg --import-owertrust < ownertrust.txt

Set master key offline

I will be necessary to restore the master key each time an action will be needed on the set of keys (adding or revoking keys, signing others key):

# get the keygrip of the master key (the one with `sec`):
$ gpg --list-keys --with-keygrip example@freedom.email
# move it to a secure storage:
$ mv $GNUPGHOME/private-keys-v1.d/${KEYGRIP}.key /my/secure/location

Reuse it

Do the exact opposite action

$ cp /my/secure/location/${KEYGRIP}.key $GNUPGHOME/private-keys-v1.d
# then actions needing the private master key can be done
$ gpg --edit-keys example@freedom.email

Revoke a key

Sub-key

# once in gpg, select the key in the list (start from 0), it will appear with
# an asterisk
$ gpg --edit-key example@freedom.email
gpg> key 2
gpg> revkey
gpg> save
# update servers
$ gpg --send-keys $FINGERPRINT

Master-key

# create revoke key 
$ gpg --output revoke-${FINGERPRINT}.asc --gen-revoke ${FINGERPRINT}
# import the revoke key in our key
$ gpg --import revoke-${FINGERPRINT}.asc
# update servers
$ gpg --send-keys $FINGERPRINT

Delete a revoked key

For a subkey use the same logic than to revoke a subkey, but use delkey command in gpg instead.

For the masterkey, it’s necessary to delete the private key before deleting the public one

$ gpg --delete-secret-key $FINGERPRINT
$ gpg --delete-key $FINGERPRINT