How to recover the GPG public key from a smartcard
Let us say you have OpenPGP card, or a javacard with the SmartPGP Applet (or hell, maybe even an implant). Let's say for the sake of argument that you have somehow lost your public key and that you foolishly didn't spread it to every GPG server on the internet.
How do you recover? Shouldn't it be on your smartcard somehow? The answer is... YES! Kinda.
How to do it
First we want to check our card with gpg --card-status
:
Reader ...........: 08E6:3437:3427286D:0
Application ID ...: D276000124010304AFAF000000000000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: unknown
Serial number ....: 00000000
Name of cardholder: name name
Language prefs ...: en
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 8
KDF setting ......: on
Signature key ....: 2741 016B 775B 6A98 1BDB 018B 3425 56BD 2FA9 A377
created ....: 2024-08-30 21:06:38
Encryption key....: F779 DC68 7AA0 F06B 5618 E53C 47E2 3218 6224 4A5A
created ....: 2024-08-30 21:06:38
Authentication key: BF59 B279 E435 6802 E071 62B6 7EF8 F677 8396 4794
created ....: 2024-08-30 21:06:38
General key info..: [none]
We need to make note of the time of each key (in this example they happen to be all the same, 2024-08-30 21:06:38
) and convert it to ISO-8601, which means no punctuation and a T
between date and time (in our example: 20240830T210638
).
Now we run gpg --faked-system-time "20240830T210638" --full-generate-key
, which is self-explanatory. At the prompt we choose to use our existing key from our card, option 14
.
gpg (GnuPG) 2.4.5; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gpg: WARNING: running with faked system time: 2024-08-30 21:06:38
Please select what kind of key you want:
(1) RSA and RSA
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(9) ECC (sign and encrypt) *default*
(10) ECC (sign only)
(14) Existing key from card
Your selection? 14
Then comes key selection, we should first select our SIGN
key (usually the first one):
Serial number of the card: D276000124010304AFAF000000000000
Available keys:
(1) 8035609870F7F80261C81D3C0C18DCA6F293EE16 OPENPGP.1 rsa4096 (cert,sign*)
(2) 42AA06A01F4C366A3B9D8073FA472B9471923F96 OPENPGP.2 rsa4096 (encr*)
(3) 30AC5119B608C3B90FDEE4633A59A5B8B8C81007 OPENPGP.3 rsa4096 (sign,auth*)
Your selection? 1
After that just go ahead and fill out all relevant information as usual.
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) 0
Key does not expire at all
Is this correct? (y/N) Y
GnuPG needs to construct a user ID to identify your key.
Real name: name
Email address:
Comment:
You selected this USER-ID:
"name"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
gpg: /tmp/tmp.tEA7KVXKO4/trustdb.gpg: trustdb created
gpg: directory '/tmp/tmp.tEA7KVXKO4/openpgp-revocs.d' created
gpg: revocation certificate stored as '/tmp/tmp.tEA7KVXKO4/openpgp-revocs.d/2741016B775B6A981BDB018B342556BD2FA9A377.rev'
public and secret key created and signed.
Note that this key cannot be used for encryption. You may want to use
the command "--edit-key" to generate a subkey for this purpose.
pub rsa4096 2024-08-30 [SC]
2741016B775B6A981BDB018B342556BD2FA9A377
uid name
Now we have the public key of the sign key, but that's not enough in itself. So we need to modify the key and add the other pubkeys from the card to complete it.
This we achieve by running gpg --faked-system-time "20240830T210638" --edit-key [key-id]
, and at the prompt running addkey
:
gpg (GnuPG) 2.4.5; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
gpg: WARNING: running with faked system time: 2024-08-30 21:06:38
Secret key is available.
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
sec rsa4096/342556BD2FA9A377
created: 2024-08-30 expires: never usage: SC
card-no: AFAF 00000000
trust: ultimate validity: ultimate
[ultimate] (1). name
gpg> addkey
And then we continue as we did earlier, but with a different key:
Secret parts of primary key are stored on-card.
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(10) ECC (sign only)
(12) ECC (encrypt only)
(14) Existing key from card
Your selection? 14
Serial number of the card: D276000124010304AFAF000000000000
Available keys:
(1) 8035609870F7F80261C81D3C0C18DCA6F293EE16 OPENPGP.1 rsa4096 (cert,sign*)
(2) 42AA06A01F4C366A3B9D8073FA472B9471923F96 OPENPGP.2 rsa4096 (encr*)
(3) 30AC5119B608C3B90FDEE4633A59A5B8B8C81007 OPENPGP.3 rsa4096 (sign,auth*)
Your selection? 2
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)
Key does not expire at all
Is this correct? (y/N) y
Really create? (y/N) y
sec rsa4096/342556BD2FA9A377
created: 2024-08-30 expires: never usage: SC
card-no: AFAF 00000000
trust: ultimate validity: ultimate
ssb rsa4096/47E2321862244A5A
created: 2024-08-30 expires: never usage: E
card-no: AFAF 00000000
[ultimate] (1). name
Repeat this for the last key as well and finish it all off with save
gpg> save
If any of the keys has a different timestamp, you will need to save in-between and re-run gpg with the appropriate faked time.
Now we should be able to run gpg --card-status
and see our pubkey info:
General key info..: pub rsa4096/342556BD2FA9A377 2024-08-30 name
sec> rsa4096/342556BD2FA9A377 created: 2024-08-30 expires: never
card-no: AFAF 00000000
ssb> rsa4096/47E2321862244A5A created: 2024-08-30 expires: never
card-no: AFAF 00000000
ssb> rsa4096/7EF8F67783964794 created: 2024-08-30 expires: never
card-no: AFAF 00000000
That's it. That's the procedure. Now you are free to export the key and back it up, or if you want, lose it again.