---
title: Update expiry of GPG keys with separate master key
date: 2019-04-30
author: James McDonald
type: post
categories:
 - Tech
---

It's nice and cosy and secure to have a separate GPG master key as described in
many articles, for example https://wiki.debian.org/Subkeys. It's also a good
idea to set expiry dates on these keys so that if all else fails, at least they
will only work for so long. But that means that every expiry interval you need
to update the expiry dates to keep using the keys. And of course, like me, you
totally remember how to do that a year (or a month, or 10 minutes) later. Right?

There is conflicting information about this, and GnuPG's documentation and UI
are terrible, so I wrote it down for us both.

For this recipe, you will need:

* One backup of your original master key, ideally in ASCII-armoured (`.asc`) format
* The passphrase for your original master key
* One GnuPG 2, at least version 2.1
* One Docker, optional

You can do all of this in a Docker container to keep things nicely separated.
You don't have to. I create a temporary `GNUPGHOME` anyway, just to be
cautious.

```
docker run -ti --rm debian
apt-get update && apt-get install -y gnupg2
```

You can run the rest of the commands inside your shiny new container.

Create a temporary GPG home and import your master key backup.

```
export GNUPGHOME=$(mktemp -d)
gpg --import
```

Just paste your master key into the terminal (finish with Ctrl-D), or however
else you want to get it into the container. Obviously look for people standing
behind you scribbling furiously. You will be asked for your passphrase.

The output will include something like:

```
gpg: key 1234ABCD1234ABCD: public key "Your Name <you@example.com>" imported
```

Stick that key ID in a variable.

```
export ID=1234ABCD1234ABCD
```

Now edit the expiry date on the master key and all subkeys. I have 3 subkeys
(encrypt, sign and auth), so that's what you see in my example.

```
gpg --edit-key $ID
expire
1y
y
# Select however many subkeys you have
key 1
key 2
key 3
expire
y
1y
y
save
```

Optionally, make a fresh backup. Copying it somewhere is left as an exercise
for the reader.

```
gpg -a --export-secret-key master > master-backup.asc
```

Push your updated public keys.

```
gpg --send-keys $ID
```

Clean up.

```
rm -rf $GNUPGHOME
```

Exit your shell and Docker will clean up the container.

That's it! On your other machines, retrieve the updated public keys with the
new expiry date.

```
gpg --recv-keys masterkeyid
```

Now if only I could work out how to get GPG agent forwarding to work...
