It can actually be done.
The instructions at atom.smasher.org/gpg/gpg-migrate.txt are now out of date.
Try this. As always, make backups, because it's really easy to mess it up.
So these are your 'old' keys:
$ gpg -K
----------------------------------
sec 2048R/712A2BBD 2013-01-29
uid Test Key 1
ssb 2048R/F0B63FDA 2013-01-29
sec 2048R/72838B89 2013-01-29
uid Test Key 2
ssb 2048R/A19F06EC 2013-01-29
sec 2048D/AC349218 2013-03-21
uid Test Key 3
ssb 2048g/179E9F47 2013-03-21
And you have created a new "master key" which has no subkeys:
sec 4096R/CB577A43 2013-03-21
uid Master Key
For simplicity's sake, I will only rehearse the procedure using the first of your "old" keys:
sec 2048R/712A2BBD 2013-01-29
uid Test Key 1
ssb 2048R/F0B63FDA 2013-01-29
Using the same procedure, you can add all of them. I recommend you add all of them at the same time, because every time you break the keys and then reassemble them you have to recreate the binding signatures, and that is a pain.
1. Use gpgsplit to split the "old" key into its constituent packets.
$ gpg --export-secret-keys 712A2BBD | gpgsplit -vp 712A2BBD_
Now look at the files it created:
$ ls
----------------------------------
712A2BBD_000001-005.secret_key
712A2BBD_000002-013.user_id
712A2BBD_000003-002.sig
712A2BBD_000004-007.secret_subkey
712A2BBD_000005-002.sig
The first file, "712A2BBD_000001-005.secret_key" contains the packet for the main private key (packet type tag 5, hence the "005") of your "old" key, "712A2BBD". (You will need this, but you will need to convert it into a subkey if you want to migrate it into your new "master key". In keys generated using standard settings on GPG, the main private key normally has usage flags "S" for sign and "C" for certify, and does not have "E" for encrypt, which is normally why the key is generated with an "E" subkey. However, because of the procedure we are using, when eventually the main key is turned into a subkey and migrated to your new "master key", it will have all usage flags ("SCEA") enabled. This probably makes it less secure, and is probably a behaviour to be avoided.)
The second file, "712A2BBD_000002-013.user_id", is the packet for the user id (packet type tag 13). (You won't need this).
The third file, "712A2BBD_000003-002.sig", is a binding signature (packet type tag 2) for these packets. (You won't need this).
The fourth file is the packet for the secret subkey (F0B63FDA) (packet type tag 7). (You will need this. Typically, a subkey like this has the "E" usage flag, meaning it is solely for encryption. However, in the process of importing it to your new "master key" it will acquire all of the usage flags, ("SCEA"), which is probably not a good thing.)
The fifth file, "712A2BBD_000005-002.sig", is the binding signature (packet type tag 2) for the subkey. You won't need it.
Save the two files you need and remove the others.
2. Change the main key (712A2BBD) into a subkey.
You don't need to do anything to the subkey (F0B63FDA) in order to migrate it to your new "master key", but the main key (712A2BBD) of your old key needs to be altered in order to make it work.
Open the main key, "712A2BBD_000001-005.secret_key", in an editor capable of making hex or binary edits. I used ghex:
$ ghex 712A2BBD_000001-005.secret_key
If you are using a hex editor, the first byte will be "95". Change it to "9D".
If you are using a binary editor, the first byte will be "10010101". Change it to "10011101".
Save it, and then use pgpdump to see if it you have been successful in changing it to a subkey. If you have been successful, you will see the following output:
$ pgpdump 712A2BBD_000001-005.secret_key | head -1
-----------------
Old: Secret Subkey Packet(tag 7)(1836 bytes)
3. Add a "dummy" subkey to your new "master key" for each of the subkeys you want to add.
Just like in the tutorial at atom.smasher.org, you will need to create new "dummy" subkeys on your "master key" in order to make sure you have keybinding signatures on the master key which can accomodate (at least at first) the migrating subkeys.
Think of it as creating "slots" for the old subkeys to slot into. You will need as many slots as keys you want to add.
In the present example, we'll make two dummy subkeys, but if you want to add all of the keys you listed in your original post, you'll want to make six.
$ gpg --expert --edit-key CB577A43
----------------------------------------
gpg (GnuPG) 1.4.12; Copyright (C) 2012 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.
pub 4096R/CB577A43 created: 2013-03-21 expires: never usage: SC
trust: unknown validity: unknown
gpg>addkey
Make sure, while going through the subkey generation wizard (which is in expert mode, thanks to the --expert option above) that when you generate your new "dummy" subkey, it is of the same...
- key strength (2048, 4096, etc)
- type (DSA, RSA, elgamal)
- usage (encrypt, sign)
...as the subkey you intend to add in that "slot".
Since we're adding two subkeys, we finish up with two new "dummy" subkeys on the "master key". Save and exit:
pub 4096R/CB577A43 created: 2013-03-21 expires: never usage: SC
trust: unknown validity: unknown
sub 2048R/AAAAAAAA created: 2014-01-01 expires: never usage: S
sub 2048R/BBBBBBBB created: 2014-01-01 expires: never usage: E
gpg> save
4. Split your new "master key" - along with its new subkeys - into its constituent packets.
$ gpg --export-secret-keys CB577A43 | gpgsplit -vp CB577A43_
You should end up with something like the following:
$ ls
----------------
CB577A43_000001-005.secret_key
CB577A43_000002-013.user_id
CB577A43_000003-002.sig
CB577A43_000004-007.secret_subkey
**CB577A43_000005-002.sig**
CB577A43_000006-007.secret_subkey
**CB577A43_000007-002.sig**
The fifth and seventh files (the ones I have put in **s) are the subkey keybinding signature packets that were generated when you generated the "dummy subkeys." You'll need these.
The fourth and sixth files are the actual "dummy subkey" packets. They can now be safely deleted (the only files you should delete.)
$ rm CB577A43_000004-007.secret_subkey CB577A43_000006-007.secret_subkey
5. "Slot in" your migrating "subkeys" into the split master key.
Steps one and two left you with two files:
712A2BBD_000001-005.secret_key (the original main key of your "old key", now edited into a subkey)
712A2BBD_000004-007.secret_subkey (the original subkey of your "old key".)
Now copy these into the folder with the split constituents of the "master key" and rename these files so that they replace the "dummy subkey" files that we just deleted.
$ mv 712A2BBD_000001-005.secret_key CB577A43_000004-007.secret_subkey
$ mv 712A2BBD_000004-007.secret_subkey CB577A43_000006-007.secret_subkey
You should once again have seven (in this example) files, but files four and six are now your old keys, all set and ready to become subkeys of your new master key.
$ ls
----------------
CB577A43_000001-005.secret_key
CB577A43_000002-013.user_id
CB577A43_000003-002.sig
**CB577A43_000004-007.secret_subkey**
CB577A43_000005-002.sig
**CB577A43_000006-007.secret_subkey**
CB577A43_000007-002.sig
6. Concatenate the files into private and public key files, ready for import
Put the files together so that they are concatenated consecutively into single files, for ease of import later.
$ cat CB577A43_000001-005.secret_key CB577A43_000002-013.user_id CB577A43_000003-002.sig CB577A43_000004-007.secret_subkey CB577A43_000005-002.sig CB577A43_000006-007.secret_subkey CB577A43_000007-002.sig > concatenated_CB577A43.secret
Use the same command, but pipe the output to gpgsplit in order to create public counterparts, before redirecting to a new file:
$ cat CB577A43_000001-005.secret_key CB577A43_000002-013.user_id CB577A43_000003-002.sig CB577A43_000004-007.secret_subkey CB577A43_000005-002.sig CB577A43_000006-007.secret_subkey CB577A43_000007-002.sig | gpgsplit --no-split --secret-to-public > concatenated_CB577A43.public
7. Back up your keyring and then delete the "old" AND "master" keys, both public and private, from your keyring.
$ cp -R ~/.gnupg/ ~/.gnupg_backup
$ gpg --delete-secret-and-public-keys CB577A43 712A2BBD
8. Download and build gnupg-1.2.0.
Recently whenever anyone tries to follow the tutorial at atom.smasher.org, the problem they run into is that, with the newest versions of gpg, once they reassemble the key and add it to their keyring, the added subkeys 1) have no usage flags, and 2) they are unable to reset the expiry date, as advised in the atom.smasher.org tutorial, a necessary step to creating new and valid keybinding signatures. The result is that after one export/import cycle, the keys are deemed invalid by GPG, and disappear from the private keyring.
In order to successfully import the keys, you have to download and build an old version of gnupg: a version from 2002 no less. One you have build it, you will be able to reset the expiry dates on the new keys, and successfully recreate valid keybindings for the keys.
Download the old gnupg.
$ wget ftp://mirror.tje.me.uk/pub/mirrors/ftp.gnupg.org/gnupg/gnupg-1.2.0.tar.bz2
$ tar -xjf gnupg-1.2.0.tar.bz2
$ cd gnupg-1.2.0/
$ ./configure
$ make
Navigate into the g10 folder, which contains your newly build gpg binary
$ cd g10
In order to use this binary, instead of the system-wide build of gpg, which is more recent, you have to type the absolute path to the binary. If you are in the same folder, use ./gpg, for example:
$ ./gpg --list-keys
8. Append the new assembled "master key" file with imported subkeys to your public and private keyrings.
Don't import the keys the normal way, because the keybinding signatures don't check out, with the result that the imported subkeys wouldn't import the normal way. Instead, cat the files to the end of your public and private keyrings.
$ cat concatenated_CB577A43.secret >> ~/.gnupg/secring.gpg
$ cat concatenated_CB577A43.public >> ~/.gnupg/pubring.gpg
Check that they have gotten in there by using the gnupg-1.2.0 to list the keys:
$ ./gpg --list-keys
-----------------
pub 4096R/CB577A43 2013-03-21
uid Master Key
sub 2048R/712A2BBD 2013-01-29
sub 2048R/F0B63FDA 2013-01-29
9. Edit the keys using the gnupg-1.2.0.
Make sure to navigate back to the build folder for gnupg-1.2.0/g10, and invoke the built binary to edit your newly imported, newly assembled master key, complete with your imported old subkeys:
$ ./gpg --edit-keys CB577A43
-----------------
sec 4096R/CB577A43 created: 2013-03-21 expires: never
ssb 2048R/712A2BBD created: 2013-01-29 expires: never
ssb 2048R/F0B63FDA created: 2013-01-29 expires: never
First, reset the passwords.
Command> passwd
It is likely that all of your old keys had different passwords from your new master key. If you reset the password now, it will prompt you for each of the passwords of the old keys in turn (along with the subkey id) and when you have inputted them all properly, it will ask you for a new key. Once this is done, they will all have the same password, avoiding weirdness later.
Second, reset the expiry date on ALL of the keys. Begin with the main master key:
Command> expiry
And then work your way through each of the subkeys, changing the expiry date on each of them.
Command> key 1
Command> expiry
Command> key 1
Command> key 2
Command> expiry
Command> key 2
Command> key 3
And so on
Make sure you change it to a value it was not on already, or there will be no change. You can change it back to the original value later on: what is required now is a change, so that gpg-1.2.0 can create new subkey binding signatures.
Once all of this is done save.
Command> save
gnupg-1.2.0 will exit and save the new keybinding signatures, validating the migration of your old keys into your new master key.
10. Now edit the keys using the standard (current) gnupg, to see if it worked.
Open the same key for editing using the standard, system-wide version of gpg, to see if it worked. If it worked, you will see two things:
- The expiry dates will be the new expiry dates you have just changed to in step 9, and not the original ones.
- The usage flags to the right of the subkeys will display "usage:SCEA"
.
$ gpg --edit-key CB577A43
--------------------------
pub 4096R/CB577A43 created: 2013-03-21 expires: [newdate] usage: SC
trust: unknown validity: unknown
sub 2048R/712A2BBD created: 2013-01-29 expires: [newdate] usage: SCEA
sub 2048R/F0B63FDA created: 2013-01-29 expires: [newdate] usage: SCEA
If it did not work, the usage flags will be blank, and the expiry date will now show the change you just made in step 9.
$ gpg --edit-key CB577A43
--------------------------
pub 4096R/CB577A43 created: 2013-03-21 expires: **never** usage: SC
trust: unknown validity: unknown
sub 2048R/712A2BBD created: 2013-01-29 expires: **never** usage:
sub 2048R/F0B63FDA created: 2013-01-29 expires: **never** usage:
Finally, you need to put it through one export/import cycle, and delete the keys in between. If it survives this, the procedure has worked.
$ gpg --export-secret-keys CB577A43 > CB577A43_new.secret
$ gpg --export CB577A43 > CB577A43_new.public
$ gpg --delete-secret-and-public-keys CB577A43
$ gpg --import CB577A43_new.secret CB577A43_new.public
$ gpg --edit-key CB577A43
--------------------------
pub 4096R/CB577A43 created: 2013-03-21 expires: [newdate] usage: SC
trust: unknown validity: unknown
sub 2048R/712A2BBD created: 2013-01-29 expires: [newdate] usage: SCEA
sub 2048R/F0B63FDA created: 2013-01-29 expires: [newdate] usage: SCEA
11. Final tasks.
Assuming it worked, you will now need to cross certify your subkeys, so that they can create and verify signatures.
$ gpg --edit-key CB577A43
And from the gpg edit prompt:
gpg> cross-certify
You will also need to reset trust:
gpg> trust
Finally, make sure to test the key rigorously, to make sure it works before you distribute it. I refer back to the atom.smasher.org tutorial for these final steps:
check all expiration dates and preferences. some of these operations may have changed your expiration dates and preferences; reset as
necessary.
test out all key components for creating and verifying signatures, and encryption/decryption. use the bang (!) to force each (sub)key:
create & verify signatures:
$ date | gpg -u '712A2BBD!' --clearsign | gpg -v --verify
$ date | gpg -u 'F0B63FDA!' --clearsign | gpg -v --verify
encrypt/decrypt:
$ date | gpg -ear '712A2BBD!' | gpg -v --decrypt
$ date | gpg -ear 'F0B63FDA!' | gpg -v --decrypt
after testing out the keys locally, send your new public key to one or two people and test all key components (sending signed/encrypted
messages to each other using all key components). make sure that they
first delete (from their keyrings) your old key! and make sure that
they understand that the key should NOT be circulated until all
functions are verified to be working!
when putting the new key into circulation, it's probably a good idea to expire/revoke the old key. include a revocation comment that
specifies the new key ID and instructions to delete the old key from
the keyring.
note on key revocation: according to the OpenPGP standards a revocation generated by a sub key will be ignored, unless that subkey
has been designated (by the primary key) as a revocation key. GnuPG
seems to behave correctly, but some versions of PGP(tm) may not. if
someone is claiming that your new key is revoked, have then remove all
of your old and current keys from their keyring: then re-import your
current key(s).