一站式PGP使用

缘起

一直想要整理一下自己的密钥体系,又看到最近 Yubikey(一个支持OTP、公钥加密签名、U2F协议的硬件认证设备 [1] 火起来了。关于个人究竟要不要使用这样复杂的身份验证技术,虽然有一些争论,但首先通过实践是一次很好的学习机会,能够对认证等有更深入的感性理解。第二,记得很多空投活动都限定 Github 的SSH Key 和 GPG key 有较早日期的绑定(如果没有设置就薅不到羊毛了)。第三,有一个固定的稳定的安全的统一认证手段很 Cool(至少可以在Homepage等地放上你的公钥装逼)。

用途

理论

Sign [S] 和 Certify [C]

Certify or Certification,证书授权。本质就是 Sign 操作,也就是用私钥对目标进行签名(其实就是加密操作,之所以不能算是真正的加密是因为只要是公钥就可以解密,而公钥人人都可以获得,所以就失去了“加密”的内涵,人人都可以知道的东西肯定不叫秘密了)。但是签名的对象通常有两种,一种是对数据进行签名,而另一种则是对 Key 密钥进行签名。我们把对数据进行签名叫做 Sign,而对密钥(Public Key)进行签名叫做 Certify。

简单来说,你先用摘要算法(如 SHA-256)给文件提取出一个指纹(摘要、哈希值等),再用私钥加密这个指纹得到一个数字签名,和文件一起发出去。别人收到文件和签名后,先计算文件的哈希值,接着用你的公钥,从数字签名中解密出你给的哈希值,和他本地计算的对比,如果两者一致,那么签名就是有效的。

Encryption [E]

是指用公钥进行加密,在非对称密钥体系中,公钥加密的内容只能通过对应的私钥才能解密。但是由于加密速度非常慢,所以公钥加密通常用在传输体积较小的数据上。

简单来说,别人用你的公钥加密数据后发给你,这些数据只有你的私钥能解密。

Authentication [A]

是指身份验证和鉴权。我们常见的认证方式就是密码登陆,但是由于密码存在暴力破解的问题,所以并不是一种非常安全的方式。通常更加安全的方式就是使用公钥认证,它的加密强度更高。公钥认证的原理跟使用公钥加密一样,服务器持有用户的公钥,只要用户持有对应的私钥(可以解密服务器下发的加密后的数据),就可以验证用户身份。

实际

  • 使用 GPG 密钥来签名你的 Git Commit
  • 使用公钥验证第三方软件的签名
  • 使用 GPG 公钥来加密你的邮件
  • 使用公钥认证来实现授权登录
  • 签名你的PDF文件
  • 等等

傻傻分不清 PGP 和 GPG

简单来说,PGP 和 GPG 都是用于加密、数字签名以及认证的软件。只是 PGP(Pretty Good Privacy)是闭源的商业软件,而 GPG (GNU Privacy Guard) 遵循 OpenPGP 协议是开源的,OpenPGP 是在 PGP 基础上定义的开放标准,因此 GPG 用于免费实现以使用 PGP 的一种工具和方法。

其中历史故事也挺有趣,可以自行翻阅。

PGP 加密体系核心概念

Key 密钥

每个 Key 都包含两部分,Public Key 公钥 和 Private Key 私钥。

Fingerprint 指纹

指纹是 Public Key 的散列值(默认使用 MD5 算法)

KeyID 密钥索引

GPG 中使用 Fingerprint 来作为 KeyID,用来标识一个 Key。Long ID 用 Fingerprint 的后 16 位字符 (HEX)来表示,Short ID 则用 Fringerprint 的后 8 位字符 (32-bit) 来表示。

UserID 用户索引

GPG 中也是用 UserID 来标识一个或多个 Key。由于 Key 必须绑定至少一个 UserID(也就是 Email 地址),所以 UerID 也可以用来标识 Key。区别是,同一个 UserID(即 Email 地址) 可以绑定多个 Keys。

一个 uid 由三个部分组成:全名(一般是实名),注释(用 ( ) 包括),邮箱地址(用 < > 包括)。

Keyring 密钥环

是指存储密钥的数据库。默认情况下,所有的本地密钥都保存在 ~/.gnupg/pubring.kbx 中

Key Server 公钥服务器

专门用于存放 Public key 的服务器

Keygrip 密钥柄

是一个独立于协议的识别公钥的方式,通过对 Key 的参数计算哈希得来。Keygrip 相比 Fingerprint 的特别之处是,它可以唯一标识一个 Key,因为它只跟你的密钥参数(如 modulus)相关,因此在 GPG 和 SSH 中,相同的 Keygrip 都表示一个相同的 Key。

Master Key 主密钥 和 Subkey 子密钥

本质上,Master key 和 Subkey 都是独立生成的,两者在生成时彼此之间并无依赖关系。但是在生成之后,GPG 用一个叫 Binding Signature 的东西把两种进行关联。简单来说就是 Master key 对 Subkey 进行签名,声明自己对 Subkey 的 Owner 关系。同时 Subkey 也对 Master Key 进行签名,声明自己对 Master Key 的 Member 关系。

另外,只有 Master Key 有 Certify 的功能。也就是说,只有 Master Key 可以对其它 Key 进行签名,Subkey 是无法这么做的。

基于网络安全中的最小权限和职责分离原则,我们通常通过 Master Key 构建单一职责的 Subkey 以使用。

RSA加密算法与ECC加密算法的区别

  • RSA加密算法:国际标准算法,应用较早的算法之一,普遍性更强,同比 ECC 算法的适用范围更广,兼容性更好,一般采用2048位的加密长度,服务端性能消耗较高。

  • ECC加密算法:椭圆加密算法,新一代算法趋势主流,一般采用256位加密长度(相当于 RSA 3072 位加密强度)更安全,抗攻击型更强,同比 RSA 算法加密速度快,效率更高,服务器资源消耗更低。
    您可以通过下表对比项目查看两种加密算法的具体区别:

对比项目ECCRSA
密钥长度256 bit2048 bit
CPU占用较少较高
内存占用较少较高
网络消耗较少较高
加密效率较高一般
抗攻击性较强一般
兼容范围新版浏览器和操作系统均支持,但存在少数不支持的平台。例如 cPanel均支持

最佳实践

准备工作

GnuPG下载

上手练习

创建 Master Key

Master Key 应该只用于 Certify,使用安全系数较高的 ed25519 椭圆曲线算法,并且永远不过期。

ZSH
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 启用专家模式
> gpg --expert --full-gen-key

gpg (GnuPG/MacGPG2) 2.2.34; Copyright (C) 2022 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.

Please select what kind of key you want:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (sign only)
(4) RSA (sign only)
(7) DSA (set your own capabilities)
(8) RSA (set your own capabilities)
(9) ECC and ECC
(10) ECC (sign only)
(11) ECC (set your own capabilities)
(13) Existing key
(14) Existing key from card
Your selection? 11

Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Sign Certify

(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished

# 这里关闭 Sign 功能,使 Master Key 仅拥有 Certify 功能。
Your selection? S

Possible actions for a ECDSA/EdDSA key: Sign Certify Authenticate
Current allowed actions: Certify

(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished

Your selection? Q
Please select which elliptic curve you want:
(1) Curve 25519
(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? 1
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

GnuPG needs to construct a user ID to identify your key.

Real name: Jing Li
Email address: lixeon.lij@gmail.com
Comment: Your Comment
You selected this USER-ID:
"Jing Li (Your Comment) <lixeon.lij@gmail.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
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.
gpg: revocation certificate stored as '/Users/lixeon/.gnupg/openpgp-revocs.d/48056EA23656CAEB32B0697C910711ACF19A5FDF.rev'
public and secret key created and signed.

pub ed25519 2022-06-21 [C]
48056EA23656CAEB32B0697C910711ACF19A5FDF
uid Jing Li (Your Comment) <lixeon.lij@gmail.com>

编辑 Master Key,为其添加 Subkey

创建4个 Subkey,分别赋予 Sign Only, Encrypt Only 和 Authenticate Only 功能。另外创建一个基于 RSA 的 Subkey 以便后面用于生成 PKCS #12 证书。

ZSH
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# 这里可以填 KeyID 也可以填 UserID
> gpg --expert --edit-key 48056EA23656CAEB32B0697C910711ACF19A5FDF

gpg (GnuPG/MacGPG2) 2.2.34; Copyright (C) 2022 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 ed25519/910711ACF19A5FDF
created: 2022-06-21 expires: never usage: C
trust: ultimate validity: ultimate
[ultimate] (1). Jing Li (Your Comment) <lixeon.lij@gmail.com>

# 新增密钥
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
(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? 1
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
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 ed25519/910711ACF19A5FDF
created: 2022-06-21 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/8A67550C0D04E806
created: 2022-06-21 expires: never usage: S
[ultimate] (1). Jing Li (Your Comment) <lixeon.lij@gmail.com>

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? 12
Please select which elliptic curve you want:
(1) Curve 25519
(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? 1
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
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 ed25519/910711ACF19A5FDF
created: 2022-06-21 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/8A67550C0D04E806
created: 2022-06-21 expires: never usage: S
ssb cv25519/4223A00DEEC08AC1
created: 2022-06-21 expires: never usage: E
[ultimate] (1). Jing Li (Your Comment) <lixeon.lij@gmail.com>

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? 11

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Sign

(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished

# 关闭 Sign 功能
Your selection? S

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions:

(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished

# 增加 Authenticate 功能
Your selection? A

Possible actions for a ECDSA/EdDSA key: Sign Authenticate
Current allowed actions: Authenticate

(S) Toggle the sign capability
(A) Toggle the authenticate capability
(Q) Finished

Your selection? Q
Please select which elliptic curve you want:
(1) Curve 25519
(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? 1
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
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 ed25519/910711ACF19A5FDF
created: 2022-06-21 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/8A67550C0D04E806
created: 2022-06-21 expires: never usage: S
ssb cv25519/4223A00DEEC08AC1
created: 2022-06-21 expires: never usage: E
ssb ed25519/E70CE91D0116DFAE
created: 2022-06-21 expires: never usage: A
[ultimate] (1). Jing Li (Your Comment) <lixeon.lij@gmail.com>

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? 4
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
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
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 ed25519/910711ACF19A5FDF
created: 2022-06-21 expires: never usage: C
trust: ultimate validity: ultimate
ssb ed25519/8A67550C0D04E806
created: 2022-06-21 expires: never usage: S
ssb cv25519/4223A00DEEC08AC1
created: 2022-06-21 expires: never usage: E
ssb ed25519/E70CE91D0116DFAE
created: 2022-06-21 expires: never usage: A
ssb rsa4096/01F2DFEFE0D26D1F
created: 2022-06-21 expires: never usage: S
[ultimate] (1). Jing Li (Your Comment) <lixeon.lij@gmail.com>

# 最后要保存
gpg> save

查看当前密钥对

ZSH
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
# 列出所有公钥、子公钥
> gpg --list-keys

# 列出所有密钥、子密钥
> gpg --list-secret-keys

# 简化命令
> gpg -k
> gpg -K

# 加上 --keyid-format long 输出长ID
# 加上 --fingerprint 输出指纹信息

/Users/lixeon/.gnupg/pubring.kbx
--------------------------------
sec# ed25519/910711ACF19A5FDF 2022-06-21 [C]
48056EA23656CAEB32B0697C910711ACF19A5FDF
uid [ultimate] Jing Li (Your Comment) <lixeon.lij@gmail.com>
ssb ed25519/8A67550C0D04E806 2022-06-21 [S]
ssb cv25519/4223A00DEEC08AC1 2022-06-21 [E]
ssb ed25519/E70CE91D0116DFAE 2022-06-21 [A]
ssb# rsa4096/01F2DFEFE0D26D1F 2022-06-21 [S]

# 缩写说明
A => Authentication
C => Certify
E => Encrypt
S => Sign
? => Unknown capability
sec => Secret Key
ssb => Secret SuBkey
pub => Public Key
sub => Public Subkey

# 带 # 号说明该密钥对的私钥在 Keyring 中被删除。建议将 Master Key 的私钥加密离线保存(打印等方式)后删除本地私钥。

导出吊销证书

GPG 的公钥因为需要被广为人知(虽然现在已不建议在 Key Server 上公布你的公钥),所以一旦私钥丢了就很麻烦,得通知所有人“我这个公钥不能信了”。因此 GPG 多了一个“吊销证书”(revocation certificate),拿着这个证书你就能证明“我就是我,我的身份证丢了,你们赶紧把丢了的那个作废”。而其他人呢,看到你在原来的证书基础之上,又发布了这么一张吊销证书,就知道原来的证书已经不可信了。

GPG 不允许用户生成子密钥的吊销证书,而是把变更都放在唯一的公钥中,简洁且不易出错。

ZSH
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
> gpg -ao revoke.pgp --generate-revocation 910711ACF19A5FDF

sec ed25519/910711ACF19A5FDF 2022-06-21 Jing Li (Your Comment) <lixeon.lij@gmail.com>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 3
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key is no longer used
(No description given)
Is this okay? (y/N) y
Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable. But have some caution: The print system of
your machine might store the data and make it available to others!

导出公钥和 Subkey 的私钥,并安全备份

其实每一个 Subkey 也都有对应的公钥,但是 Master Key 的公钥记录了所有信息,建议一步到位直接用 Master Key 的公钥。

ZSH
1
2
3
4
5
6
# 导出公钥
> gpg -ao public-key.asc --export Jing Li

# 注意这里最后 要带上“!”, 不然会导出全部子密钥
# 导出主私钥,建议secret-key 替换为你的加密设备备份文件的路径,直接导入到设备中
> gpg -ao secret-key --export-secret-key 8A67550C0D04E806!

使用 RSA 密钥对 生成 PKCS #12 证书

我们也许会需要 PKCS #12 证书,这时候可以借助 gpgsm 工具转换生成。

目前还不支持 ECC 加密算法的密钥对直接转换。

ZSH
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# 列出密钥对的 Keygrip
> gpg --list-secret-keys --with-keygrip --keyid-format long

sec ed25519/910711ACF19A5FDF 2022-06-21 [C]
48056EA23656CAEB32B0697C910711ACF19A5FDF
Keygrip = CF630DF3C1ABCDCE7A0D0D97652665CA747C8B54
uid [ultimate] Jing Li (Your Comment) <lixeon.lij@gmail.com>
ssb ed25519/8A67550C0D04E806 2022-06-21 [S]
Keygrip = E4C04F000AFB26BD0FDA169A947487DEAB01A81F
ssb cv25519/4223A00DEEC08AC1 2022-06-21 [E]
Keygrip = 975C2507B74245E6E5265ED7024F61434E9DE673
ssb ed25519/E70CE91D0116DFAE 2022-06-21 [A]
Keygrip = 083EAAB08F49E7182BB94AE2E496F4DE463B6CA9
ssb rsa4096/01F2DFEFE0D26D1F 2022-06-21 [S]
Keygrip = 8DA3C421E5AC294858D5EB0E16370052413AC9F2

# 用 gpgsm 生成一个 X.509 证书
> gpgsm --gen-key -o temporary.cert
gpgsm (GnuPG/MacGPG2) 2.2.34; Copyright (C) 2022 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.

# 选择已有 key,利用上述 RSA 的 Subkey 进行转换
Please select what kind of key you want:
(1) RSA
(2) Existing key
(3) Existing key from card
Your selection? 2

Enter the keygrip: 8DA3C421E5AC294858D5EB0E16370052413AC9F2
Possible actions for a RSA key:
(1) sign, encrypt
(2) sign
(3) encrypt
# 我们希望这个证书仅用于签名
Your selection? 2

# 输入 X.509 的属性信息,这里 subject 缩写有一套规则
# 以下述为例,其他缩写请自行查找 X.509 subject
C => countryName
L => locality
CN => commonName

Enter the X.509 subject name: C=China, L=Pingchao Nantong, CN=Jing Li
Enter email addresses (end with an empty line):
> lixeon.lij@gmail.com
>
Enter DNS names (optional; end with an empty line):
>
Enter URIs (optional; end with an empty line):
>

# 生成自签名证书
Create self-signed certificate? (y/N) y
These parameters are used:
Key-Type: RSA
Key-Length: 1024
Key-Grip: 8DA3C421E5AC294858D5EB0E16370052413AC9F2
Key-Usage: sign
Serial: random
Name-DN: C=China, L=Pingchao Nantong, CN=Jing Li
Name-Email: lixeon.lij@gmail.com

Proceed with creation? (y/N) y
Now creating self-signed certificate. This may take a while ...
gpgsm: about to sign the certificate for key: &8DA3C421E5AC294858D5EB0E16370052413AC9F2
gpgsm: certificate created
Ready.

# 将上述新建证书导入到 gpgsm 的 Keyring
> gpgsm --import temporary.cert

# 查看证书信息
> gpgsm --list-keys

ID: 0x2A3F701A
S/N: 54D72CD2DF743152
(dec): 6113404303382425938
Issuer: /CN=Jing Li/L=Pingchao Nantong/C=China
Subject: /CN=Jing Li/L=Pingchao Nantong/C=China
aka: lixeon.lij@gmail.com
validity: 2022-06-21 11:40:41 through 2063-04-05 17:00:00
key type: 4096 bit RSA
key usage: digitalSignature nonRepudiation
chain length: unlimited
fingerprint: 40:84:E7:76:73:CE:F4:DF:74:97:C1:8C:25:BC:31:2B:2A:3F:70:1A
sha2 fpr: E1:E0:DE:AA:7A:48:63:2B:6B:5B:56:F5:6A:83:57:87:CE:7F:15:D3:CD:9D:FC:F3:15:06:D3:23:76:83:84:ED

# 导出 PKCS #12 证书
> gpgsm -o cert.p12 --export-secret-key-p12 ${KEY_ID}

# 注意上述 cert.p12 中包含 keys 和 certificates
# 你可以通过下述命令分离它们,并同时转换为 pem 格式证书
> openssl pkcs12 -in secret-key.p12 -nocerts -out gpg-key.pem
> openssl pkcs12 -in secret-key.p12 -nokeys -out gpg-certs.pem

真正使用

断网生成密钥

为了安全性,建议在一台断网的电脑上生成你的密钥对。

特别推荐使用 Tails 发行版,系统自带 gpg 和 paperkey 等工具, 可以确保全程断网操作, 同时此系统重启会擦除所有内容,还免去了擦除密钥的麻烦。 需要工具:

  • 一台电脑
  • 一个装有Tails系统的U盘 0 , 使用它生成密钥
  • 一个已经全盘加密的U盘/TF卡 1(推荐),或者智能卡(如 Yubikey),用来存储主密钥
  • 一个智能卡 (推荐) ,或者已经全盘加密的U盘/TF卡 2,用来存放子密钥,日常使用

公布公钥,但谨慎将公钥上传到 Key Server

我们可以有多种方式公布公钥,包括但不限于社交媒体、个人主页、线下交换等。

文章 [2] 中也讨论了发布公钥到 Key Server 导致的隐私泄漏等问题,可以参考。

使用 PGP 为 Git Commit 签名

只要你 PGP 的 UserID 包含 Git Config 中的邮箱, 使用

ZSH
1
> git commit -S -m your commit message

即可签名。

使用 PGP 收发加密邮件

使用 PGP 进行 SSH 登录

使用 PGP 转换的 PKCS #12 证书对 PDF 文件签名

Reference

  1. https://en.wikipedia.org/wiki/YubiKey
  2. https://ulyc.github.io/2021/01/13/2021年-用更现代的方法使用PGP-上/
  3. https://zhuanlan.zhihu.com/p/481900853
  4. https://cloud.tencent.com/document/product/400/54179
Author

Jing Li

Posted on

2022-06-21

Updated on

2022-08-08

Licensed under

Comments