It's said to be a good practice to sometimes ro-ro-rotate your keys. It shortens the time span duging which your communications might be snooped upon if your key was compromised without your knowledge.

It's especially interesting to do it whenever there's a security issue like the one that was disclosed last week, cve-2016-0777 and cve-2016-0778, for which keys might have been exposed for 5 years to bein extracted by a malicious server.

I use monkeysphere to link my pubkey material to PGP the web of trust. This makes it super easy to make the pubkey available, and to have servers verify that the key it's getting was actually validated by some peers.

Here's how I rotated my key pair with monkeysphere.

Generate new subkey

First things first. Since we want to rotate keys, we need a new key. Monkeysphere does this for us and makes it super easy.

Before actually doing, though, let's take a look at my key before the process starts for comparative measures afterwards).

pub   4096R/0xC28592496BABC122 2014-06-11 [expires: 2016-06-10]
      Key fingerprint = C1CC 7A4B 7FBE 8ED3 7C00  F8B5 C285 9249 6BAB C122
uid                 [ultimate] Gabriel Filion <gabster@lelutin.ca>
uid                 [ultimate] Gabriel Filion <gabriel@koumbit.org>
sub   4096R/0x59BC891D96B9EF51 2014-06-11 [expires: 2016-06-10]
sub   4096R/0xC613C0506BBF1403 2014-09-18

You can see that I already have a subkey on the last line. That's the one I want to replace. So let's create the new key:

monkeysphere gen-subkey -l 4096

After this operation is complete, you should be able to notice a new subkey on your PGP key:

pub   4096R/0xC28592496BABC122 2014-06-11 [expires: 2016-06-10]
      Key fingerprint = C1CC 7A4B 7FBE 8ED3 7C00  F8B5 C285 9249 6BAB C122
uid                 [ultimate] Gabriel Filion <gabster@lelutin.ca>
uid                 [ultimate] Gabriel Filion <gabriel@koumbit.org>
sub   4096R/0x59BC891D96B9EF51 2014-06-11 [expires: 2016-06-10]
sub   4096R/0xC613C0506BBF1403 2014-09-18
sub   4096R/0x595B733A8B95E6F1 2016-01-23

Export new subkey to ssh-agent alongside old one

This part should be super simple if you have only one secret key in your keyring. Just launch the command at the end of this section and you're done. However, in my case I have a key that's revoked and monkeysphere tries to export material from this key. In order to prevent this, I use the environment variable MONKEYSPHERE_SUBKEYS_FOR_AGENT that I set in my ~/.bashrc file.

Let's get each subkey's fingerprint. Some users might need to use this super intuitive gpg call. For some others, only one argument is needed; I haven't yet determined what influences this, but in all cases using the argument twice will work for everyone.

$ gpg --fingerprint --fingerprint gabster@lelutin.ca
[...]
pub   4096R/0xC28592496BABC122 2014-06-11 [expires: 2016-06-10]
      Key fingerprint = C1CC 7A4B 7FBE 8ED3 7C00  F8B5 C285 9249 6BAB C122
uid                 [ultimate] Gabriel Filion <gabster@lelutin.ca>
uid                 [ultimate] Gabriel Filion <gabriel@koumbit.org>
sub   4096R/0x59BC891D96B9EF51 2014-06-11 [expires: 2016-06-10]
      Key fingerprint = CB3D 48CE 55CD 1FAB B1E4  D0C3 59BC 891D 96B9 EF51
sub   4096R/0xC613C0506BBF1403 2014-09-18
      Key fingerprint = 39C9 47C6 48F4 664C FFBB  C83A C613 C050 6BBF 1403
sub   4096R/0x595B733A8B95E6F1 2016-01-23
      Key fingerprint = D480 05C9 0B18 ABF7 965C  7E01 595B 733A 8B95 E6F1

Now that we have this information, we can adjust the environment variable. Monkeysphere's man page says that the variable takes a space-separated list of fingerprints so I removed all spaced from the output above:

export MONKEYSPHERE_SUBKEYS_FOR_AGENT="D48005C90B18ABF7965C7E01595B733A8B95E6F1 39C947C648F4664CFFBBC83AC613C0506BBF1403"

Finally, we can export the new subkey to the ssh agent:

monkeysphere s

After this, you should be seeing in the output of ssh-add -L the same thing as in monkeysphere u 'gabster@lelutin.ca'

Revoke old subkey

Now we can revoke the old subkey. Doing so will not stop monkeysphere from exporting it to ssh-agent. It simply creates a public revocation object on the subkey's public part.

gpg --edit uid
> key 2
> revkey
> save

(optional) publish updated PGP key to key servers

If you are using the public key servers for publishing your public key material, now is a good time to send your updated key.

gpg --send-keys gabster@lelutin.ca

Revoked subkeys that are published to key servers won't get imported by monkeysphere-authentication update-users anymore; they will actually get removed from computers (after all that's the point of monkeysphere, to import only public keys that are valid). So once this runs on computers to which you should have access, only you new subkey should be present on computers.

Of course, for this to actually happen you will have to wait for propagation to happen between the key servers.

For people that use other means of publishing keys, you'll have to send your updated public key to the right communication channel for your key to end up getting updated by monkeysphere.

Install new key everywhere

If you're only using your subkey for monkeysphere-enabled computers, then you're all done! But if you're installing this same public key on computers that are not using monkeysphere (e.g. the traditional authorized_keys way), you'll have to install your new key everywhere and remove the old one.

You can get your new public key in a format that's usable with authorized_keys with:

monkeysphere u 'gabster@lelutin.ca'

Clear out old subkey

Once you're certain that the old key is not installed anywhere anymore, you can stop exporting it to your ssh-agent. For this, we'll change the environment variable again and remove the old subkey's fingerprint.

export MONKEYSPHERE_SUBKEYS_FOR_AGENT="D48005C90B18ABF7965C7E01595B733A8B95E6F1"

You can then clean out the old key from your running agent. First manually export the new value of the variable you just set in your ~/.bashrc. Then remove keys from your agent (for this part you might want to be more careful and use -d to export single keys if you have other identities present in your ssh-agent) and if you blasted everything out like I did, re-export key material from monkeysphere:

ssh-add -D
monkeysphere s

Rotation completed!