Connexer Ltd. Masthead

Improve the Security of Your OpenPGP Key by Using Subkeys

Revision History

Revision Date Revised by Comments
0.11 20131230 RCS Change references to "GPG subkeys" to "OpenPGP subkeys" (Thanks to Daniel Kahn Gillmor for the pointer)
0.1 20131217 RCS Updated and improved content; added CC license
0.0 20100519 RCS Initial draft

Copyright

This article is copyright © 2010,2013 Connexer Ltd.


Licensing

Creative Commons License
This article is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Table of Contents

Introduction
What Are Subkeys?
Advantages
Disadvantages
Tweaking This Guide
Caveat
Step-by-step Guide

Introduction

The information in this article was adapted from "Using multiple subkeys in GPG" by Adrian von Bidder <avbidder+gpg@fortytwo.ch> (original URL: http://fortytwo.ch/gpg/subkeys).

The purpose of this article is to make it easier for the reader to more securely manage his or her GPG key through the use of OpenPGP subkeys. Understanding that this can potentially make overall management of your GPG key more challenging, there are very good reasons to take an approach like this. There are also some drawbacks. This article will briefly discuss the advantages and disadvantages.

What Are Subkeys?

First, it is worth explaining what subkeys are. Subkeys are a feature of OpenPGP which allows keys which are subordinate to the main OpenPGP key. They can be identified with their own key fingerprint, but are most often associated with the fingerprint of the main key. Please note that this is not meant to be a comprehensive or exhaustive explanation of the concept of subkeys, but rather touches only on the points important to the author. There is an abundance of documentation on all aspects of OpenPGP and GPG, which the reader is encouraged to consult for a more thorough understanding. There are two main uses of OpenPGP: encryption, and signing. When you create an OpenPGP key with GPG (which is the focus of this article), you create two subkeys by default: one for encryption and one for signing. The subkeys discussed in this article are only used for signing. The reason for this is that it is impossible to sensibly employ multiple encryption subkeys. A simple explanation for this is that when someone goes to send you an encrypted message, that person has no way of knowing which possible subkey (assuming you have more than one) ought to be used to encrypt the message. The only sensible thing would be to distribute the public part of every encryption subkey and then anybody encrypting anything to you would need to send you the same message once for each encryption subkey you have created. This could certainly be problematic. Having said that, implementing the approach detailed in this article will not provide any additional protection to your encryption subkey. That means that if your device is lost or compromised, you would have a concern that whomever acquired your GPG key could potentially decrypt anything encrypted to you. There are ways around this (e.g., using a smart card or other hardware token) but they are beyond the scope of this article. As far as signing subkeys, it is very simple (from an infrastructure perspective) to handle multiple subkeys. They all associate to their primary key, so anything signed by any subkey can be associated with the main key and can hence be considered to be signed by the same person.

Advantages

There are a number of advantages to employing the approach documented here to managing your GPG key. The principal reason is that should you have your GPG secret key loaded on a mobile device and that device is stolen, you will find yourself with a serious problem. If you do not have a backup of your key stored somewhere, you are stuck generating a new key. Even if you do have a backup somewhere, you will be left wondering if the key on the mobile device has been compromised in some way. Even in a controlled situation (e.g., sending a laptop in for warranty repair), as opposed to having a device stolen, letting someone else have control of your secret key may be unacceptable. By employing the approach detailed in this article, if a subkey is lost or compromised, it can simply and be revoked and a new one issued without having to generate and entirely new GPG key. This results in significantly less impact to the web of trust. Another advantage to the approach detailed in this article is that storing the primary secret key on offline removable media means that it is impossible for a system or device compromise to result in a compromise of the primary secret key. Of course, the media containing the primary secret key would need to be properly protected.

Disadvantages

It is also important to note that there are some disadvantages. Keeping the primary secret key on removable media makes signing other GPG keys problematic, since the primary secret key must be loaded in order to do the signing. Additionally, using expiration dates with the subkeys (as is recommended in this article) means that the subkeys must be extended prior to expiration, or new subkeys issued if they are allowed to expire. The approach that I take is that I make subkeys good for one year, and queue up all the keys which I will sign until 60-90 days before the subkeys will expire. At that point, I will load the primary secret key, sign all the keys I have queued up throughout the year and then extend the expiration dates of the subkeys at the same time. Note that I do not place an expiration date on the primary key. I want it to be good forever. Occasionally someone will request that I sign their key right away and then I will have to go through part of this exercise. This article also recommends using different passphrases for each subkey, which could be a headache if you have many passwords and passphrases to remember. Another disadvantage is that other people who use your public key (i.e., to verify something you have signed) may receive errors about your key being expired if they do not regularly update their GPG keyrings based on the public keyservers.

Tweaking This Guide

Please note that the approach that detailed in this article does not employ every possible tactic that a truly paranoid person would likely want to employ. For example, at one point the steps below will have you remove various secret keys and transfer them to your different systems using scp. If you are really paranoid, you will want to employ utilities like wipe(1) and you will probably want to use something other than scp to move the keys. Additionally, this article has you do certain things which you may think are too extreme, like placing your primary secret key onto a removable media and removing it entirely from your systems so that it is only stored offline. You may choose to modify the approaches recommended here to suit your specific needs.

Caveat

There is also one important caveat with regards to the output shown in this article. They keys I used at the time I initially wrote this article are considered insecure by more modern standards. When I initially created my GPG key in 2005, it was common to use 1024 bit DSA keys for signing and 2048 bit keys for encryption. Those were the GPG defaults, if I recall correctly. I have since discontinued using these keys and have upgraded to 4096 bit RSA keys for both signing and encryption. That said, the procedure remains the same, even if the output has changed slightly.

Step-by-step Guide

What follows below is a step-by-step guide to implementing the subkey management approach summarized above. This article assumes that you have already created the subkeys which you wish to manage and that you already know to which systems you wish to transfer them.

  1. Create a backup of your GPG directory:
     cp -a ~/.gnupg ~/.gnupg.orig
    

    If you are doing this for the first time, i.e., you have just created your subkeys, then you can skip over steps 2 through 5, as those are only relevant if you have already done this once. In which case you have stored your primary secret key to removable media and then need to reload it in order to proceed with the subkey renewal and other steps detailed below.

  2. Check for the presence of the secret key:
     roberto@desktop:~$ gpg --list-secret-keys
     /network/home/roberto/.gnupg/secring.gpg
     ----------------------------------------
     sec#  1024D/B2B97BB1 2005-10-01
     uid                  Roberto C. Sanchez <roberto@familiasanchez.net>
     uid                  Roberto C. Sanchez <sanchezr@ieee.org>
     uid                  Roberto C. Sanchez <roberto@connexer.com>
     ssb   2048g/D27DA3A2 2005-10-01
     ssb   1024D/A7C89464 2006-07-15
    

    In my case, I have three subkeys which I manage. One subkey is for use on my home/office network, while each of the other two subkeys are for my two laptops. In the listing above, the primary key is listed first, with each of its associated user IDs (GPG keys can multiple identities associated with them), followed by the encryption subkey, 2048g/D27DA3A2 in this case, and one of my signing subkeys, 1024D/A7C89464. The hash (#) after "sec" listed before the primary key indicates that the secret key is not present. The first key listed is always the primary key. So, in this instance, only the public part of the primary key is present. The dates correspond to the creation date of each key or subkey.

  3. Mount the removable media containing your primary secret key:
     mount /mnt/cdrom/
    
  4. Copy only the secret ring from your removable media into your GPG home directory:
     cp /mnt/cdrom/gnupg.bak/secring.gpg ~/.gnupg/
    

    The reason to copy in only the secret key is that if you have taken the approach of storing your primary secret key on removable media you may have updates to your public keyring that you do not want to overwrite. For example, if you have retrieved new public keys or if GPG has performed trustdb updates. This ensures that you don't lose those updates. Toward the end of this procedure you will backup your updated GPG home directory with all the secret keys and all the updated expiration dates.

  5. Check for the presence of the secret key:
     roberto@desktop:~$ gpg --list-secret-keys
     /network/home/roberto/.gnupg/secring.gpg
     ----------------------------------------
     sec   1024D/B2B97BB1 2005-10-01
     uid                  Roberto C. Sanchez <roberto@familiasanchez.net>
     uid                  Roberto C. Sanchez <sanchezr@ieee.org>
     uid                  Roberto C. Sanchez <roberto@connexer.com>
     ssb   2048g/D27DA3A2 2005-10-01
     ssb   1024D/42B5A9F6 2006-07-15
     ssb   1024D/A7C89464 2006-07-15
     ssb   1024D/C0050B4F 2006-07-15
    

    There is no hash (#) after the "sec" corresponding to the first key, indicating that both public and secret parts of the key are present. The end of the output indicates that the encryption subkey and all three signing subkeys are present.

  6. Set new expiration dates:
     roberto@desktop:~$ gpg --edit-key B2B97BB1
     Secret key is available.
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 2
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub* 1024D/A7C89464  created: 2006-07-15  expires: 2008-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2008-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> expire
     Changing expiration time for a subkey.
     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
     Is this correct? (y/N)
     Key is valid for? (0) 384
     Key expires at Wed 15 Jul 2009 07:46:39 PM EDT
     Is this correct? (y/N) y
     
     You need a passphrase to unlock the secret key for
     user: "Roberto C. Sanchez <roberto@connexer.com>"
     1024-bit DSA key, ID B2B97BB1, created 2005-10-01
     
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub* 1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2008-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 2
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2008-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 3
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/42B5A9F6  created: 2006-07-15  expires: 2008-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> expire
     Changing expiration time for a subkey.
     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) 384
     Key expires at Wed 15 Jul 2009 07:47:07 PM EDT
     Is this correct? (y/N) y
     
     You need a passphrase to unlock the secret key for
     user: "Roberto C. Sanchez <roberto@connexer.com>"
     1024-bit DSA key, ID B2B97BB1, created 2005-10-01
     
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 3
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 4
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/C0050B4F  created: 2006-07-15  expires: 2008-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> expire
     Changing expiration time for a subkey.
     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) 384
     Key expires at Wed 15 Jul 2009 07:47:32 PM EDT
     Is this correct? (y/N) y
     
     You need a passphrase to unlock the secret key for
     user: "Roberto C. Sanchez <roberto@connexer.com>"
     1024-bit DSA key, ID B2B97BB1, created 2005-10-01
     
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 4
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> Save changes? (y/N) y
    

    You will note that I did not use 365 for the number of days until the next expiration. That is because the subkeys were set to expire on the 15th of July, and I wanted to extend them for exactly one year. Since I was going through this exercise nearly a month prior to the expiration, I needed to add the number of days remaining until the original expiration to get the extension to be exactly one year.

  7. Backup your GPG home directory with all the secret keys in it:
     cp -a ~/.gnupg ~/.gnupg.bak
    

    This backup will be used several times as it contains the full secret keyring with all the secret keys (for both the primary and subkeys).

  8. Export the public key and primary secret key:
     roberto@desktop:~$ gpg --export B2B97BB1 >pubkey.gpg
     roberto@desktop:~$ file pubkey.gpg
     pubkey.gpg: GPG key public ring
     roberto@desktop:~$ gpg --export-secret-keys B2B97BB1 >secret_primary_key.gpg
     roberto@desktop:~$ file secret_primary_key.gpg
     secret_primary_key.gpg: PGP key security ring
    

    The exported public key can be posted on a website or in some other public place to allow others to verify things that you have signed or to encrypt something to you. A later step also uploads the keys to a public key server.

  9. Delete the second and third subkeys:
     roberto@desktop:~$ gpg --edit-key B2B97BB1
     Secret key is available.
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 3
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 4
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> delkey
     Do you really want to delete the selected keys? (y/N) y
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> Save changes? (y/N) y
    

    This step makes it possible to export just the secret part of the first subkey. This is important because having multiple subkeys does you no good if you put the secret part of every subkey in every place. The maximum benefit is realized by placing only a single secret subkey on each device. Then a loss or compromise of a device only necessitates revoking and replacing a single subkey.

  10. Export the single remaining subkey:
     roberto@desktop:~$ gpg --export-secret-subkeys B2B97BB1 >desktop_secret_subkey.gpg
    
  11. Remove the GPG home directory that only contains a single secret subkey:
     roberto@desktop:~$ rm -rf ~/.gnupg
    
  12. Restore the backup GPG home directory with all the secret keys:
     roberto@desktop:~$ cp -a ~/.gnupg.bak ~/.gnupg
    
  13. Delete the first and third subkeys:
     roberto@desktop:~$ gpg --edit-key B2B97BB1
     Secret key is available.
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 2
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub* 1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> key 4
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub* 1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub* 1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> delkey
     Do you really want to delete the selected keys? (y/N) y
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Command> Save changes? (y/N) y
    
  14. Export the single remaining subkey:
     roberto@desktop:~$ gpg --export-secret-subkeys B2B97BB1 >laptop1_secret_subkey.gpg
    
  15. Repeat 11 through 14 for other subkeys.
  16. Remove the GPG home directory that only contains a single secret subkey:
     roberto@desktop:~$ rm -rf ~/.gnupg
    
  17. Restore the backup GPG home directory with all the secret keys:
     roberto@desktop:~$ cp -a ~/.gnupg.bak/ ~/.gnupg
    
  18. Update public key on keyservers:
     roberto@desktop:~$ gpg --send-keys B2B97BB1
     gpg: sending key B2B97BB1 to hkp server subkeys.pgp.net
    
  19. Create a backup of all the pertinent parts:
     roberto@desktop:~$ mkdir burn
     roberto@desktop:~$ cp -a ~/.gnupg burn/gnupg.bak
     roberto@desktop:~$ cp *.gpg burn/
     roberto@desktop:~$ genisoimage -J -r -V GPG\ backup -o gpg.iso burn
     I: -input-charset not specified, using utf-8 (detected in locale settings)
     Unknown file type (unallocated) burn/.. - ignoring and continuing.
     Using PUBRI000.GPG;1 for  burn/gnupg.bak/pubring.gpg~ (pubring.gpg)
     Using GPG_A000.;1 for  burn/gnupg.bak/gpg-agent-info (gpg-agent-info-desktop)
      70.91% done, estimate finish Thu Jun 26 20:22:04 2008
     Total translation table size: 0
     Total rockridge attributes bytes: 2005
     Total directory bytes: 5162
     Path table size(bytes): 46
     Max brk space used 0
     7057 extents written (13 MB)
    

    You can create the ISO image and burn it to CD/DVD media or you can copy the files to a USB device, or whatever backup medium you prefer.

  20. Prepare the new GPG home directories:
     roberto@desktop:~$ cp -a ~/.gnupg ~/.gnupg.laptop1
     roberto@desktop:~$ cp -a ~/.gnupg ~/.gnupg.laptop2
     roberto@desktop:~$ cp desktop_secret_subkey.gpg ~/.gnupg/secring.gpg
     cp: overwrite `.gnupg/secring.gpg'? y
     roberto@desktop:~$ cp laptop2_secret_subkey.gpg ~/.gnupg.laptop2/secring.gpg
     cp: overwrite `.gnupg.laptop2/secring.gpg'? y
     roberto@desktop:~$ cp laptop1_secret_subkey.gpg ~/.gnupg.laptop1/secring.gpg
     cp: overwrite `.gnupg.laptop1/secring.gpg'? y
    

    This step creates the GPG home directories for the two laptops and copies into each GPG home directory (including the one for the current host) the secret keyrings that contain only a single subkey secret key and omit the primary secret key. The fully populated secret key is preserved in the burn/ directory.

  21. Verify the primary secret key is gone and only the secret subkey remains:
     roberto@desktop:~$ gpg --list-secret-keys
     /network/home/roberto/.gnupg/secring.gpg
     ----------------------------------------
     sec#  1024D/B2B97BB1 2005-10-01
     uid                  Roberto C. Sanchez <roberto@familiasanchez.net>
     uid                  Roberto C. Sanchez <sanchezr@ieee.org>
     uid                  Roberto C. Sanchez <roberto@connexer.com>
     ssb   2048g/D27DA3A2 2005-10-01
     ssb   1024D/A7C89464 2006-07-15
    

    Recall, you are looking for the hash (#) after the "sec" associated with the first subkey to indicate that the secret part of the primary key is not present.

  22. Set the new passphrases:
     roberto@desktop:~$ gpg --homedir ~/.gnupg.laptop1 --edit-key B2B97BB1 passwd
     Secret key is available.
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Secret parts of primary key are not available.
     
     You need a passphrase to unlock the secret key for
     user: "Roberto C. Sanchez <roberto@connexer.com>"
     2048-bit ELG-E key, ID D27DA3A2, created 2005-10-01
     
     Enter the new passphrase for this secret key.
     
     
     Command> Save changes? (y/N) y
     roberto@desktop:~$ gpg --homedir ~/.gnupg.laptop2 --edit-key B2B97BB1 passwd
     Secret key is available.
     
     pub  1024D/B2B97BB1  created: 2005-10-01  expires: never       usage: SC
                          trust: ultimate      validity: ultimate
     sub  2048g/D27DA3A2  created: 2005-10-01  expires: never       usage: E
     sub  1024D/A7C89464  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/42B5A9F6  created: 2006-07-15  expires: 2009-07-15  usage: S
     sub  1024D/C0050B4F  created: 2006-07-15  expires: 2009-07-15  usage: S
     [ultimate] (1). Roberto C. Sanchez <roberto@connexer.com>
     [ultimate] (2)  Roberto C. Sanchez <roberto@familiasanchez.net>
     [ultimate] (3)  Roberto C. Sanchez <sanchezr@ieee.org>
     
     Secret parts of primary key are not available.
     
     You need a passphrase to unlock the secret key for
     user: "Roberto C. Sanchez <roberto@connexer.com>"
     2048-bit ELG-E key, ID D27DA3A2, created 2005-10-01
     
     Enter the new passphrase for this secret key.
     
     
     Command> Save changes? (y/N) y
    

    I consider this step to be very important. While simply using subkeys helps protect you against someone impersonating you if your device is lost or compromised, it is theoretically possible for that person to brute force your passphrase. For that reason, I use a different passphrase for each keyring after I have separated out the secret subkeys. That way, each of the three (in my case) secret keyrings has only my encryption subkey and one signing subkey, along with having a different passphrase than my other secret keyrings. So, in the event of a compromise, I revoke the compromised subkey and issue a new one with a new passphrase.

  23. Transfer each new GPG home directory over to its respective host:
     roberto@desktop:~$ scp -r ~/.gnupg.laptop1/* laptop1:~/.gnupg/
     gpg-agent-info            100%   75     0.1KB/s   00:00
     gpg-agent-info-desktop    100%   75     0.1KB/s   00:00
     gpg-agent.conf            100%   23     0.0KB/s   00:00
     gpg.conf                  100% 8096     7.9KB/s   00:00
     pub_key.asc               100% 6004     5.9KB/s   00:00
     pubring.gpg               100% 6829KB   6.7MB/s   00:01
     pubring.gpg~              100% 6829KB   3.3MB/s   00:02
     random_seed               100%  600     0.6KB/s   00:00
     revcert-B2B97BB1.asc      100%  264     0.3KB/s   00:00
     secring.gpg               100% 2252     2.2KB/s   00:00
     trustdb.gpg               100%   30KB  30.4KB/s   00:00
     roberto@desktop:~$ scp -r ~/.gnupg.laptop2/* laptop2:~/.gnupg/
     gpg-agent-info            100%   75     0.1KB/s   00:00
     gpg-agent-info-desktop    100%   75     0.1KB/s   00:00
     gpg-agent.conf            100%   23     0.0KB/s   00:00
     gpg.conf                  100% 8096     7.9KB/s   00:00
     pub_key.asc               100% 6004     5.9KB/s   00:00
     pubring.gpg               100% 6829KB   6.7MB/s   00:00
     pubring.gpg~              100% 6829KB   6.7MB/s   00:01
     random_seed               100%  600     0.6KB/s   00:00
     revcert-B2B97BB1.asc      100%  264     0.3KB/s   00:00
     secring.gpg               100% 2252     2.2KB/s   00:00
     trustdb.gpg               100%   30KB  30.4KB/s   00:00
    

    If you are paranoid, you will likely not want to use scp to transfer the GPG home directories.

If you managed to read this whole thing, please let me know what you thought, whether it was useful, or if you have any suggestions for improvement.

Articles


- Name and Email Validation: You Are Doing It Wrong - How to Ship Your Own Self-Signed Certificate Authority - Improve the Security of Your OpenPGP Key by Using Subkeys - Redeliver the Contents of an mbox - Customizing Debian Packages - Setting up a Debian Package Repository
More useful content ...

Top of Page