For some reason, I was missing my UID on my secret ring, although it existed on my public ring, this is a story about what happened and what I did to fix it.
I don’t know why/how this happened, but someone pointed out to me that they had a similar problem and the reason for the missing uid in the secret key was that they had added the uid on their desktop computer and sent the public key to the keyserver. Later, they refreshed the keys on their laptop from the keyserver, which made the new uid appear in the public key, but of course not in the secret key.
Many thanks to dkg who I could not have done this without.
If I edit my key:
micah@lillypad> gpg --edit-key 7355FAFF
Secret key is available.
pub 1024D/7355FAFF created: 2000-12-31 expires: never usage: SC
trust: ultimate validity: ultimate
sub 2048g/C252AFCD created: 2000-12-31 expires: never usage: E
sub 2048R/3EFFEA75 created: 2008-09-02 expires: never usage: A
[ultimate] (1). Micah Anderson <micah@riseup.net>
[ultimate] (2) Micah Anderson <micah@debian.org>
[ultimate] (3) Micah Anderson <micah@indymedia.org>
[ultimate] (4) Micah Johan Anderson <micah@riseup.net>
You see that I have UIDs in my public part of my key. However, as soon as I switch to the secret keyring, I am missing UIDs:
Command> toggle
sec 1024D/7355FAFF created: 2000-12-31 expires: never
ssb 2048g/C252AFCD created: 2000-12-31 expires: never
I could also see this by doing the following:
micah@lillypad> gpg --list-secret-keys
./secring.gpg
-------------
sec 1024D/7355FAFF 2000-12-31
ssb 2048g/C252AFCD 2000-12-31
I discovered this when I had first exported my secret keys to a file, and then attempted to re-import them:
micah@lillypad> gpg --export-secret-keys 7355faff > 7355faff
micah@lillypad> mv ~/.gnupg/secring.gpg{,.bak}; touch ~/.gnupg/secring.gpg; chmod 600 secring.gpg
micah@lillypad> gpg --import < 7355faff
gpg: key 7355FAFF: no user ID
gpg: Total number processed: 1
gpg: secret keys read: 1
Although it processed and read one secret key, because there was no user ID, it didn’t actually import it:
micah@lillypad> gpg --list-secret-keys
micah@lillypad>
Nothing there!
If I added verbosity to the import, it shows that the exported secret keyfile that I had simply did not have any uid packets:
micah@lillypad> gpg --verbose --import --verbose < 7355faff
:secret key packet:
version 4, algo 17, created 978297126, expires 0
skey[0]: [1024 bits]
skey[1]: [160 bits]
skey[2]: [1022 bits]
skey[3]: [1023 bits]
iter+salt S2K, algo: 3, simple checksum, hash: 2, salt: 8245d6357e5321f7
protect count: 96
protect IV: b7 3a 0c 97 ee 45 9d a8
encrypted stuff follows
:secret sub key packet:
version 4, algo 16, created 978297145, expires 0
skey[0]: [2048 bits]
skey[1]: [3 bits]
skey[2]: [2048 bits]
iter+salt S2K, algo: 3, simple checksum, hash: 2, salt: 8245d6357e5321f7
protect count: 96
protect IV: 3e dc 21 58 78 4d bd a4
encrypted stuff follows
:signature packet: algo 17, keyid C4E00BB37355FAFF
version 4, created 978297145, md5len 0, sigclass 0x18
digest algo 2, begin of digest c2 a0
hashed subpkt 2 len 4 (sig created 2000-12-31)
subpkt 16 len 8 (issuer key ID C4E00BB37355FAFF)
data: [160 bits]
data: [160 bits]
gpg: sec 1024D/7355FAFF 2000-12-31
gpg: key 7355FAFF: no user ID
gpg: Total number processed: 1
gpg: secret keys read: 1
That shows a secret key packet, a secret subkey packet, and a signature packet, but no user_id packet!
Arg… I know I have a userid on the public part, and its been self-signed, but the secret part doesn’t have it, and now it wont import it.
This is how I solved it.
- First I created two directories, one for the secret key, and one for the public key, and then I exported them and sent that export through gpgsplit, which splits up the packets into individual components:
micah@lillypad> mkdir sec ; cd sec
micah@lillypad> gpg --export-secret-keys 7355FAFF | gpgsplit
micah@lillypad> ls
000001-005.secret_key 000002-007.secret_subkey 000003-002.sig
micah@lillypad> cd ..
micah@lillypad> mkdir pub
micah@lillypad> gpg --export 7355FAFF | (cd pub && gpgsplit)
micah@lillypad> cd pub
micah@lillypad> ls
000001-006.public_key 000179-002.sig 000357-002.sig 000535-002.sig
000002-013.user_id 000180-002.sig 000358-002.sig 000536-002.sig
000003-002.sig 000181-002.sig 000359-002.sig 000537-002.sig
000004-002.sig 000182-002.sig 000360-002.sig 000538-002.sig
000005-002.sig 000183-002.sig 000361-002.sig 000539-002.sig
000006-002.sig 000184-002.sig 000362-002.sig 000540-002.sig
....
I have a bunch of signatures so I didn’t list them all. I also have four user_ids on my key:
micah@lillypad> ls *user_id*
000002-013.user_id 000127-013.user_id 000329-013.user_id 000532-013.user_id
So, first I backed up my secring.gpg file, and created an empty one:
micah@lillypad> cd ~/.gnupg
micah@lillypad> mv secring.gpg secring.gpg.bak; touch secring.gpg; chmod 600 secring.gpg
Then I decided I would try to import all the secret key packets in order by concatenating them all together, and slap on the end all my user_id packets:
micah@lillypad> cat 000001-005.secret_key 000002-007.secret_subkey 000003-002.sig ../pub/*user_id* | gpg --import
gpg: key 7355FAFF: secret key imported
gpg: key 7355FAFF: no valid user IDs
gpg: this may be caused by a missing self-signature
gpg: Total number processed: 1
gpg: w/o user IDs: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
[2] micah@lillypad> gpg --list-secret-keys ~/sec
/home/micah/.gnupg/secring.gpg
------------------------------
sec 1024D/7355FAFF 2000-12-31
ssb 2048g/C252AFCD 2000-12-31
uid Micah Anderson <micah@debian.org>
uid Micah Anderson <micah@riseup.net>
uid Micah Anderson <micah@indymedia.org>
uid Micah Johan Anderson <micah@riseup.net>
Close, it actually imported it without the user-id this time! Thats a step forwards, but I want those user-ids, and the hint about the missing self-signature made me realize I should also bring in the signature packets. It appears as if packets are typically assembled with the user_id packet followed immediately by the signature packet, I decided to import the concatenation of the user_id packet, and the signature packet that followed immediately thereafter.
First I re-created an empty secring.gpg file:
micah@lillypad> rm ../.gnupg/secring.gpg
Then I concatenated them all together and imported them:
micah@lillypad> cat 000001-005.secret_key 000002-007.secret_subkey 000003-002.sig `ls ../pub | grep -A1 user_id | grep -v '^--$'` | gpg --import
gpg: keyring `/home/micah/.gnupg/secring.gpg' created
gpg: key 7355FAFF: secret key imported
gpg: key 7355FAFF: "Micah Anderson <micah@riseup.net>" 1 new signature
gpg: Total number processed: 1
gpg: new signatures: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
Voila! Now if I export the secring and try and import it, I dont get that error any longer:
micah@lillypad> gpg --export-secret-keys 7355FAFF > test
micah@lillypad> mv ~/.gnupg/secring.gpg secring.gpg_test
micah@lillypad> gpg --import ../sec/test
gpg: keyring `/home/micah/.gnupg/secring.gpg' created
gpg: key 7355FAFF: secret key imported
gpg: key 7355FAFF: "Micah Anderson <micah@riseup.net>" not changed
gpg: Total number processed: 1
gpg: unchanged: 1
gpg: secret keys read: 1
gpg: secret keys imported: 1
Hooray!