Protecting your private master key in GnuPG 2.1 and later

by Rudd-O published 2016/01/17 00:20:40 GMT+0, last modified 2016-01-17T00:20:40+00:00
How to remove the private master key from your keyring in the latest version of GnuPG.

GnuPG supports a mode of operation that lets you store just enough of your key to sign messages you send and decrypt messages sent to you.  It's especially useful when you have a device that you won't trust with the private master key part of your key.  For example, you'd like to be able to sign, encrypt and decrypt email on a device, but you may not want that device to be trusted with the ability to sign other folks' keys or modify any part of your key.

Formerly, this was accomplished by exporting a partial key (without the master key), but as of GnuPG 2.1 the option export-reset-subkey-passwd, stopped working, breaking most online how-to guides.  Here is how it works in the latest version of GnuPG -- it's not much different, but it's certainly changed.

Note: once the master private key is absent, you will not be able to add identities to your key, change the attributes of existing identities, or sign other folks' keys.  These consequences are, in a manner of speaking, the very points intended by this exercise.  Not to worry, though — if future you would like to do any one of these operations, you can always restore the master private key from another machine (or a backup) containing the directory .gnupg/private-keys.v1.d — this is the directory where GnuPG 2.1 and later stores all private keys.  You did make a backup, right?

Adding a new key for encryption

By default, GPG keys are created with one key for signing and another key for decryption.  Since we will be removing the first, master private key, you need to create a subkey for signing if e.g. you plan on signing messages sent to others or checking signatures of messages received by you.  If that's not the case, you can skip this step.

The following example assumes that GPGKEYID is the short ID of your key.  Bold is text you type, italics is what GnuPG tells you, and text beginning with hashes are comments.

# Edit the key
gpg2 --edit-key 0A05F7A7
# GnuPG shows you the edit key screen
gpg (GnuPG) 2.1.9; Copyright (C) 2015 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  rsa2048/0A05F7A7
     created: 2016-01-17  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/B4EF2594
     created: 2016-01-17  expires: never       usage: E   
[ultimate] (1). araeist <nsreit@rsneit.com>

gpg>
# Now enter addkey
addkey
Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
# Enter the number corresponding to
# 'sign only' of the strongest algorithm.
3
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 
# 4096 sounds good
4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
# One year sounds good, let's enter that.
1y
Key expires at Mon 16 Jan 2017 12:10:22 AM UTC
Is this correct? (y/N) 
# Confirm.
y
Really create? (y/N)
# Confirm again.
y

At this point GnuPG will ask you to input the passphrase for the new subkey about to be created, and then will prompt you for the passphrase of the master private key.  Here is the result:

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec  rsa2048/0A05F7A7
     created: 2016-01-17  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa2048/B4EF2594
     created: 2016-01-17  expires: never       usage: E   
ssb  rsa2048/FC39E072
     created: 2016-01-17  expires: 2017-01-16  usage: S   
[ultimate] (1). araeist <nsreit@rsneit.com>

gpg>
# Now save the results
save

With the new subkey for signing saved, you are ready to splice your master private key out of your keyriing.

Spinning off a new copy of your key without its master private key

The following example assumes that GPGKEYID is the short ID of your key, .gnupg is the directory where you keep your complete key (including the private master key) and newgnupg is the directory where you want your partial key (without the private master key) to be stored.  Presumably you would move the newgnupg directory to the equipment where you'll use it after this process.

GPGKEYID=<your GPG key ID>
# First, note the keygrip corresponding to your master
# private key.  It will be the first listed on the
# output of the following command.  That keygrip
# is the name of a .key file inside the directory
# .gnupg/private-keys.v1.d/ and that file contains
# your master private key.  Back it up now!
gpg2 --list-secret-keys --with-keygrip
# Now, export the secret subkeys.
# GnuPG will ask you for your passphrase if there is any.
# Enter it.
gpg2 --export-secret-subkeys $GPGKEYID > /tmp/priv
# Now export the public keys.
gpg2 --export $GPGKEYID > /tmp/pub
# GnuPG will now ask you for your passphrase and then
# it will import only the subkeys exported earlier.
gpg2 --homedir newgnupg --import < /tmp/priv
# Now import the publick keys exported earlier.
gpg2 --homedir newgnupg --import < /tmp/pub
# Finally, if this keyring will be used in an unattended
# process, you may want to strip the passphrase away.
# Set an empty passphrase on each key you are asked about.
gpg2 --homedir tempgnupg --passwd $GPGKEYID

Presto.  The directory tempgnupg now exclusively contains a copy of all your subkeys, possibly without a passphrase, and ready to be used on another computer without the privileges that the master private key bestows.

But what if I already have backed up my .gnupg directory and all I want is to remove the master private key in it?

Not to worry, this is even easier:

# First, list your secret keys by keygrip.
gpg2 --list-secret-keys --with-keygrip
# Now visually identify and copy the keygrip corresponding
# to your master private key.  Then:
KEYGRIP=<paste the keygrip>
rm ~/.gnupg/private-keys.v1.d/$KEYGRIP.key

Bingo.  The master private key is gone.  Remember, however, that computers can save private key material in other unexpected places (RAM, secondary caches like SSDs, temporary directories, swap partitions).  Therefore, if it's imperative that the master private key never have touched any permanent storage on the machine you're working on, the process above this section is more suited for that.