如何在不使用密钥服务器的情况下从 OpenPGP 智能卡获取 public 密钥?
How to get public key from an OpenPGP smart card without using key servers?
我正在处理一个用例,其中使用 OpenPGP 在智能卡 (Yubikey) 上生成 public 密钥对。
然后将智能卡运送给用户。
尝试在本地模拟此操作,正在执行以下操作:
- 在智能卡上生成密钥
- 删除 GnuPG 主目录
- 访问智能卡以重新生成 GnuPG 主目录
问题是在执行上述步骤后我无法测试加密文件,因为 public 密钥似乎丢失了。 fetch
好像不行。
现阶段我不想在任何在线服务器上共享 public 密钥。
删除密钥环后,是否有任何方法可以从智能卡中检索 public 密钥?
以下是正在执行的步骤:
$ gpg --card-edit
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240102010006046314290000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04631429
Name of cardholder: sm sm
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: sm
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: 54D4 E469 7056 B390 AE72 CAA1 A507 3320 7876 0302
created ....: 2017-10-11 13:16:52
Encryption key....: ADA3 2D7F 8D66 4F34 C04A 457C DFEB E3E4 A8F1 8611
created ....: 2017-10-11 11:14:18
Authentication key: 18B9 7AB4 0723 46F4 C23A 3DD7 E5C0 6A93 049E F6A8
created ....: 2017-10-11 11:14:18
General key info..: [none]
gpg/card> admin
Admin commands are allowed
gpg/card> generate
Make off-card backup of encryption key? (Y/n) n
gpg: Note: keys are already stored on the card!
Replace existing keys? (y/N) y
What keysize do you want for the Signature key? (4096)
What keysize do you want for the Encryption key? (4096)
What keysize do you want for the Authentication key? (4096)
Key is valid for? (0) 0
Is this correct? (y/N) y
Real name: john doe
Email address: john.doe@foobar.com
Comment:
You selected this USER-ID:
"john doe <<john.doe@foobar.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
gpg: /home/xxx/.gnupg/trustdb.gpg: trustdb created
gpg: key 6825CB0EBDA94110 marked as ultimately trusted
gpg: directory '/home/xxx/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/xxx/.gnupg/openpgp-revocs.d/6858F119E93FB74BB561DE556825CB0EBDA94110.rev'
public and secret key created and signed.
gpg/card> list
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240102010006046314290000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04631429
Name of cardholder: sm sm
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: sm
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: 6858 F119 E93F B74B B561 DE55 6825 CB0E BDA9 4110
created ....: 2017-10-11 13:18:11
Encryption key....: BE05 7FDF 9ACD 05F0 B75A 570F 4711 4B69 A622 C1DC
created ....: 2017-10-11 13:18:11
Authentication key: 7275 2C47 B1EF BFB5 1E6D 0E65 31C7 7DBE 2D22 7E32
created ....: 2017-10-11 13:18:11
General key info..: pub rsa4096/6825CB0EBDA94110 2017-10-11 john doe <<john.doe@foobar.com>
sec> rsa4096/6825CB0EBDA94110 created: 2017-10-11 expires: never
card-no: 0006 04631429
ssb> rsa4096/31C77DBE2D227E32 created: 2017-10-11 expires: never
card-no: 0006 04631429
ssb> rsa4096/47114B69A622C1DC created: 2017-10-11 expires: never
card-no: 0006 04631429
gpg/card> quit
$ rm -rf .gnupg/
$ gpg --card-status
gpg: directory '/home/smalatho/.gnupg' created
gpg: new configuration file '/home/smalatho/.gnupg/dirmngr.conf' created
gpg: new configuration file '/home/smalatho/.gnupg/gpg.conf' created
gpg: keybox '/home/smalatho/.gnupg/pubring.kbx' created
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240102010006046314290000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04631429
Name of cardholder: sm sm
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: sm
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: 6858 F119 E93F B74B B561 DE55 6825 CB0E BDA9 4110
created ....: 2017-10-11 13:18:11
Encryption key....: BE05 7FDF 9ACD 05F0 B75A 570F 4711 4B69 A622 C1DC
created ....: 2017-10-11 13:18:11
Authentication key: 7275 2C47 B1EF BFB5 1E6D 0E65 31C7 7DBE 2D22 7E32
created ....: 2017-10-11 13:18:11
General key info..: [none]
需要用户在删除GNUPGHOME目录之前手动导出public密钥,然后重新导入智能卡中的public密钥。
$ gpg --armor --export j.doe@example.com > public.asc
$ rm -rf ~/.gnupg
$ gpg --import public.asc
OpenPGP 智能卡没有存储足够的信息来重建完整的 OpenPGP public 密钥。您必须单独导入 public 密钥——在密钥服务器上共享它是一种解决方案,但您也可以 gpg --export
密钥,稍后再 gpg --import
以进行测试。
根据 GnuPG 的维护者的说法,it is technically possible to reconstruct the public key using only information from the card但这并不容易:
However, if you really lost the public key and you need it back, it is possible to re-create the public key with the same fingerprint. There is no code for this, you need to hack the source.
What you need is the creation timestamp and the public key parameters
from the card. You can gather this information using
$ gpg-connect-agent
> scd learn --force
S SERIALNO D276000124010101000100xxxxxxxxxx 0
S APPTYPE OPENPGP
[...]
S KEY-TIME 1 1136130759
S KEY-TIME 2 1136132140
S KEY-TIME 3 1136131786
[...]
OK
> /decode
> /hex
> scd readkey OPENPGP.1
D[0000] 28 31 30 3A 70 75 62 6C 69 63 2D 6B 65 79 28 33 (10:public-key(3
D[0010] 3A 72 73 61 28 31 3A 6E 31 32 39 3A 00 D0 99 19 :rsa(1:n129:....
[...]
OK
Take the creation time from the KEY-TIME lines. I used /decode
and /hex
above only for readability. You should use
> /datafile out
> scd readkey OPENPGP.1
OK
> /bye
instead which writes the s-expression with the public key to the file out
. The Libgcrypt functions take those s-expressions as arguments. Now you need to feed it to gpg to create the public key part and the self-signatures.
我正在处理一个用例,其中使用 OpenPGP 在智能卡 (Yubikey) 上生成 public 密钥对。
然后将智能卡运送给用户。 尝试在本地模拟此操作,正在执行以下操作:
- 在智能卡上生成密钥
- 删除 GnuPG 主目录
- 访问智能卡以重新生成 GnuPG 主目录
问题是在执行上述步骤后我无法测试加密文件,因为 public 密钥似乎丢失了。 fetch
好像不行。
现阶段我不想在任何在线服务器上共享 public 密钥。 删除密钥环后,是否有任何方法可以从智能卡中检索 public 密钥?
以下是正在执行的步骤:
$ gpg --card-edit
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240102010006046314290000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04631429
Name of cardholder: sm sm
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: sm
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
Signature key ....: 54D4 E469 7056 B390 AE72 CAA1 A507 3320 7876 0302
created ....: 2017-10-11 13:16:52
Encryption key....: ADA3 2D7F 8D66 4F34 C04A 457C DFEB E3E4 A8F1 8611
created ....: 2017-10-11 11:14:18
Authentication key: 18B9 7AB4 0723 46F4 C23A 3DD7 E5C0 6A93 049E F6A8
created ....: 2017-10-11 11:14:18
General key info..: [none]
gpg/card> admin
Admin commands are allowed
gpg/card> generate
Make off-card backup of encryption key? (Y/n) n
gpg: Note: keys are already stored on the card!
Replace existing keys? (y/N) y
What keysize do you want for the Signature key? (4096)
What keysize do you want for the Encryption key? (4096)
What keysize do you want for the Authentication key? (4096)
Key is valid for? (0) 0
Is this correct? (y/N) y
Real name: john doe
Email address: john.doe@foobar.com
Comment:
You selected this USER-ID:
"john doe <<john.doe@foobar.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
gpg: /home/xxx/.gnupg/trustdb.gpg: trustdb created
gpg: key 6825CB0EBDA94110 marked as ultimately trusted
gpg: directory '/home/xxx/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/xxx/.gnupg/openpgp-revocs.d/6858F119E93FB74BB561DE556825CB0EBDA94110.rev'
public and secret key created and signed.
gpg/card> list
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240102010006046314290000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04631429
Name of cardholder: sm sm
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: sm
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: 6858 F119 E93F B74B B561 DE55 6825 CB0E BDA9 4110
created ....: 2017-10-11 13:18:11
Encryption key....: BE05 7FDF 9ACD 05F0 B75A 570F 4711 4B69 A622 C1DC
created ....: 2017-10-11 13:18:11
Authentication key: 7275 2C47 B1EF BFB5 1E6D 0E65 31C7 7DBE 2D22 7E32
created ....: 2017-10-11 13:18:11
General key info..: pub rsa4096/6825CB0EBDA94110 2017-10-11 john doe <<john.doe@foobar.com>
sec> rsa4096/6825CB0EBDA94110 created: 2017-10-11 expires: never
card-no: 0006 04631429
ssb> rsa4096/31C77DBE2D227E32 created: 2017-10-11 expires: never
card-no: 0006 04631429
ssb> rsa4096/47114B69A622C1DC created: 2017-10-11 expires: never
card-no: 0006 04631429
gpg/card> quit
$ rm -rf .gnupg/
$ gpg --card-status
gpg: directory '/home/smalatho/.gnupg' created
gpg: new configuration file '/home/smalatho/.gnupg/dirmngr.conf' created
gpg: new configuration file '/home/smalatho/.gnupg/gpg.conf' created
gpg: keybox '/home/smalatho/.gnupg/pubring.kbx' created
Reader ...........: 1050:0404:X:0
Application ID ...: D2760001240102010006046314290000
Version ..........: 2.1
Manufacturer .....: Yubico
Serial number ....: 04631429
Name of cardholder: sm sm
Language prefs ...: en
Sex ..............: unspecified
URL of public key : [not set]
Login data .......: sm
Signature PIN ....: not forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 4
Signature key ....: 6858 F119 E93F B74B B561 DE55 6825 CB0E BDA9 4110
created ....: 2017-10-11 13:18:11
Encryption key....: BE05 7FDF 9ACD 05F0 B75A 570F 4711 4B69 A622 C1DC
created ....: 2017-10-11 13:18:11
Authentication key: 7275 2C47 B1EF BFB5 1E6D 0E65 31C7 7DBE 2D22 7E32
created ....: 2017-10-11 13:18:11
General key info..: [none]
需要用户在删除GNUPGHOME目录之前手动导出public密钥,然后重新导入智能卡中的public密钥。
$ gpg --armor --export j.doe@example.com > public.asc
$ rm -rf ~/.gnupg
$ gpg --import public.asc
OpenPGP 智能卡没有存储足够的信息来重建完整的 OpenPGP public 密钥。您必须单独导入 public 密钥——在密钥服务器上共享它是一种解决方案,但您也可以 gpg --export
密钥,稍后再 gpg --import
以进行测试。
根据 GnuPG 的维护者的说法,it is technically possible to reconstruct the public key using only information from the card但这并不容易:
However, if you really lost the public key and you need it back, it is possible to re-create the public key with the same fingerprint. There is no code for this, you need to hack the source.
What you need is the creation timestamp and the public key parameters from the card. You can gather this information using
$ gpg-connect-agent > scd learn --force S SERIALNO D276000124010101000100xxxxxxxxxx 0 S APPTYPE OPENPGP [...] S KEY-TIME 1 1136130759 S KEY-TIME 2 1136132140 S KEY-TIME 3 1136131786 [...] OK > /decode > /hex > scd readkey OPENPGP.1 D[0000] 28 31 30 3A 70 75 62 6C 69 63 2D 6B 65 79 28 33 (10:public-key(3 D[0010] 3A 72 73 61 28 31 3A 6E 31 32 39 3A 00 D0 99 19 :rsa(1:n129:.... [...] OK
Take the creation time from the KEY-TIME lines. I used
/decode
and/hex
above only for readability. You should use> /datafile out > scd readkey OPENPGP.1 OK > /bye
instead which writes the s-expression with the public key to the file
out
. The Libgcrypt functions take those s-expressions as arguments. Now you need to feed it to gpg to create the public key part and the self-signatures.