YubiKey 与 GPG 的二三事

xiaoyv_404

准备 GPG

创建子密钥

从安全角度,主密钥应当仅用于签署子密钥,创建后应该离线妥善保存。而日常工作则使用子密钥。

要创建新的子钥,得执行 gpg --expert --edit-key <id> 来编辑主密钥,在编辑模式下执行 addkey 即可根据引导添加子密钥。

YubiKey 5 Series 系列已经全系列提供了对 OpenPGP 3.4 的支持^文章 ,所以,我们这里使用 ECC 加密算法。

下面是操作的流程

跳过流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
$ gpg --expert --edit-key 0
gpg (GnuPG) 2.3.4; Copyright (C) 2021 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.

Secret key is available.

sec rsa4096/C163760892C70B65
created: 2022-04-16 expires: never usage: SCA
trust: ultimate validity: ultimate
ssb rsa4096/8A4B8653339FE236
created: 2022-04-16 expires: never usage: E
[ultimate] (1). xiaoyv_404 (OutLook) <xiaoyv_404@outlook.com>
[ultimate] (2) xiaoyv_404 <xiaoyv_404@xiaoyv404.top>

gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(12) ECC (encrypt only)
(13) Existing key
(14) Existing key from card
Your selection? 10
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(2) Curve 448
(3) NIST P-256
(4) NIST P-384
(5) NIST P-521
(6) Brainpool P-256
(7) Brainpool P-384
(8) Brainpool P-512
(9) secp256k1
Your selection?
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) 5y
Key expires at 2028/1/29 16:34:19 �й���׼ʱ��
Is this correct? (y/N) y
Really create? (y/N) y
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.

sec rsa4096/C163760892C70B65
created: 2022-04-16 expires: never usage: SCA
trust: ultimate validity: ultimate
ssb rsa4096/8A4B8653339FE236
created: 2022-04-16 expires: never usage: E
ssb ed25519/1F9E54CC2965751B
created: 2023-01-30 expires: 2028-01-29 usage: S
[ultimate] (1). xiaoyv_404 (OutLook) <xiaoyv_404@outlook.com>
[ultimate] (2) xiaoyv_404 <xiaoyv_404@xiaoyv404.top>

注意! 添加完成后在编辑模式,执行 q 退出,会询问是否保存,选择 Y。注意如果这时候按 ctrl+c 强退了就不会保存刚才的修改。

为什么我会知道呢

备份

在把密钥添加到 YubiKey 之前,先导出备份。因为这是「移动」而不是「复制」,同时 YubiKey 不允许导出内部密钥。执行

1
$ gpg --armor --export-secret-keys --export-options backup -o /path/to/save/backup.gpg <id>

新的 GPG 工具,只需导出主密钥的私钥,即可自动包含主+子密钥的公钥+私钥。

  • --armor 参数可以导出文本格式。缩写为 -a
  • --export-options backup 可导出用于备份目的的密钥,其包含了恢复所需的全部数据,不仅有 OpenPGP 定义的内容,还包括 GunPG 附加数据。

恢复

备份就自然有恢复

1
$ gpg --import --import-options restore /path/to/backup.gpg
  • --import-options restore 导入一些常规导入中跳过的数据,包括 GunPG 专有数据。

吊销

万一有一天,自己的密钥泄漏了或者说不想用这个密钥了怎么办,这时候就要请出我们的吊销证书啦!通过吊销证书我们可以在没有密钥、无需密码的吊销私钥。所以,吊销证书也需要妥善保存。

生成

1
$ gpg --output /path/to/save/revoke.asc --gen-revoke <id>

吊销

1
2
# 声明作废,不要轻易执行
gpg --import /path/to/save/revoke.asc

现在,你需要把吊销后的密钥(不是吊销密钥本身)重新分发,例如上传到 Key Server,让其他人知道这个公钥已经不可信了。

但是我没实践过

添加到 YubiKey

现在请出我们的 YubiKey !插到电脑上,执行 gpg --card-status应该可以读取到 YubiKey 的 GPG 状态。读取不到的话请检查连接。

1
2
3
4
5
6
7
$ gpg  --card-status
Reader ...........: Yubico YubiKey OTP FIDO CCID 0
Application ID ...: D2760001240100000006208196060000
Application type .: OpenPGP
Version ..........: 0.0
Manufacturer .....: Yubico
# .....

将密钥导入到 YubiKey 中

再次编辑主密钥 gpg --expert --edit-key <id>,默认选中的是主密钥 (0),可以执行 key <x> 来选择子密钥,x 为顺序号 (0, 1, 2…)。某密钥被选中后,前面会出现 * 的标志,但是主密钥除外。

1
2
3
4
5
6
7
8
9
gpg> key 2 # 选择第二个子密钥

sec rsa4096/C163760892C70B65
created: 2022-04-16 expires: never usage: SCA
trust: ultimate validity: ultimate
ssb rsa4096/8A4B8653339FE236
created: 2022-04-16 expires: never usage: E
ssb* ed25519/5294C7EFDE9F9284
created: 2023-01-30 expires: 2028-01-29 usage: S

注意!!!! 使用 keytocard 将密钥传输到 YubiKey 中将是一个不可逆的单向操作,请在继续之前将密钥妥善备份!!!!!

选中后执行 keytocard 就可以导入 YubiKey 啦,根据密钥的用途选择对应的存储槽就好。

异常处理

可是我在执行的时候 GPG 提示我 Invalid name 怎么办啊

1
2
gpg> keytocard
gpg: error getting current key info: Invalid name

不用惊慌,这时候可以尝试更新 GPG 版本下载链接在这里

配置公钥地址

拥有公钥+私钥,才可以正常进行签名等操作。可惜 YubiKey 本身不保存公钥,这意味如果使用一台新设备,则部分功能可能受限。如果公钥上没有很重要的隐私信息,一个方便的方案是将其传到 Key Server,或者 Gayhub Github。然后将公钥下载地址配置到 YubiKey 里。例如已经把公钥配置到了 Github,那么地址就是 https://github.com/<username>.gpg,执行下面命令将其配置到 YubiKey

1
2
3
4
$ gpg --edit-card
gpg/card> admin
gpg/card> url https://github.com/<username>.gpg
gpg/card> q

那么在新设备上,就可以执行下面的命令获取并导入公钥:

1
2
$ gpg --edit-card
gpg/card> fetch

与 Git 的那些事

首先使用 gpg -k --keyid-format long 列出所有的密钥:

1
2
3
4
5
6
7
8
9
$ gpg -k --keyid-format long
C:\Users\xiaoyv_404\AppData\Roaming\gnupg\pubring.kbx
-----------------------------------------------------
pub rsa4096/C163760892C70B65 2022-04-16 [SCA]
4265AAF12F95BF07228E2A92C163760892C70B65
uid [ultimate] xiaoyv_404 (OutLook) <xiaoyv_404@outlook.com>
uid [ultimate] xiaoyv_404 <xiaoyv_404@xiaoyv404.top>
sub rsa4096/8A4B8653339FE236 2022-04-16 [E]
sub ed25519/5294C7EFDE9F9284 2023-01-30 [S] [expires: 2028-01-29]

最好是选用一个 [S] [^1] 标记的密钥,记下 ID,我这里选择的是 5294C7EFDE9F9284。执行:

1
2
git config --global user.signingkey "[yourKeyID]"
git config --global commit.gpgsign true

这样的话提交的时候就可以自动签名啦 :D

参考

[^1]: Sign 签名

  • Title: YubiKey 与 GPG 的二三事
  • Author: xiaoyv_404
  • Created at : 2023-05-01 00:00:00
  • Updated at : 2024-06-01 06:00:00
  • Link: https://www.xiaoyv404.com/56/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments