GPG 的正确使用姿势
一篇“最硬核”的 GPG 使用指南
{{< featuredImage >}}
这篇指南面向的是对 GPG 有一定基础的同学,如果你连 GPG 是什么都不知道的话可能需要先了解一些基础知识
前面的一篇文章提到了如果使用 GPG 创建密钥,以及如果使用 GPG 签名 Git Commit 和 Git Tag,但其中提到的使用方法实际上并不标准。
后来经过大量的学习与思考,总结出了这篇“最硬核”的 GPG 使用指南,你当然不需要完全照着文章中操作,但核心思想还是可以参考一下的。
虽说是“最硬核”的 GPG 使用指南,但我仍然会尽我所能用最通俗的语言让每个人都能看懂。
首先需要准备两个 U 盘,为了方便区分,就分别标注他们为 0号U盘
和 1号U盘
。U 盘大小没有要求,50 M 都绰绰有余了 {{< spoiler >}}现在应该买不到这样的 U 盘了吧 |・ω・`){{< /spoiler >}}但是必须保证 U 盘安全无毒。
核心思想🔗
其实本文的核心思想总结起来就一句话:我们应该使用且只使用子密钥,主密钥应该放在一个绝对安全的地方。
创建密钥对🔗
让我们来创建一个新的 GPG 密钥对,强烈建议在无网的 Linux 虚拟机环境中操作
在「使用 GPG 签名你的 Git Commit」这篇文章中,我们使用的是 --gen-key
来生成 GPG 密钥对,这样可以快速的生成一个可用的密钥对,但有的细节性的设置却不好设置
这里我们使用 --full-gen-key
来生成密钥对,首先选择密钥类型,选择 1
(默认) 即可
$ gpg --full-gen-key
gpg (GnuPG) 2.2.15; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
请选择您要使用的密钥类型:
(1) RSA 和 RSA (默认)
(2) DSA 和 Elgamal
(3) DSA(仅用于签名)
(4) RSA(仅用于签名)
您的选择是? 1
然后选择密钥长度,没有特殊需求的话保持 2048
的默认选项即可
RSA 密钥的长度应在 1024 位与 4096 位之间。
您想要使用的密钥长度?(2048) 2048
然后设置密钥的有效期,因为我们需要长期使用,所以选择 0
,密钥永不过期
请设定这个密钥的有效期限。
0 = 密钥永不过期
<n> = 密钥在 n 天后过期
<n>w = 密钥在 n 周后过期
<n>m = 密钥在 n 月后过期
<n>y = 密钥在 n 年后过期
密钥的有效期限是?(0) 0
确定后,依次输入姓名、电子邮件和注释 (可以不填),然后选择 o
确定
GnuPG 需要构建用户标识以辨认您的密钥。
真实姓名: Mogeko
电子邮件地址: zhengjunyi@live.com
注释:
您选定了此用户标识:
“Mogeko <zhengjunyi@live.com>”
更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? o
然后输入并确认你密钥的密码
在这个步骤中可以做些其他操作,因为
我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数发生器有更好的机会获得足够的熵
如果看到一下输出就说明生成成功了
gpg: 密钥 71C861745213C7DC 被标记为绝对信任
gpg: 吊销证书已被存储为‘/home/mogeko/.gnupg/openpgp-revocs.d/7E99AAF646B8B572979266C471C861745213C7DC.rev’
公钥和私钥已经生成并被签名。
pub rsa2048 2019-05-30 [SC]
7E99AAF646B8B572979266C471C861745213C7DC
uid Mogeko <zhengnyi@live.com>
sub rsa2048 2019-05-30 [E]
创建子密钥🔗
我们刚刚生成的密钥名为 71C861745213C7DC
,这个同时也是我们的公钥。无论加密还是签名都可以直接使用这个公钥,但我们并不推荐这样做,因为如果直接使用这个公钥,而密钥又不小心被泄露了,我们就不得不吊销整个密钥。
为了解决这一问题,我们应该使用且只使用子密钥,这样如果子密钥被泄露了,我们仅需要吊销被泄露的子密钥,这样主密钥仍是安全的,然后用主密钥生成新的子密钥继续使用。
生成主密钥对的时候 GPG 已经为我们生成了一对有效期与主密钥相同,ElGamal
(仅用于加密) 的子密钥对,但我们最好还是生成和使用一对新的子密钥。
想要生成子密钥,我们需要使用 GPG 选项 --edit-key
+ 密钥名称
编辑密钥,然后输入 GPG 命令 addkey
$ gpg --edit-key 71C861745213C7DC
gpg (GnuPG) 2.2.15; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
私钥可用。
sec rsa2048/71C861745213C7DC
创建于:2019-05-30 有效至:永不 可用于:SC
信任度:绝对 有效性:绝对
ssb rsa2048/57440229D371DCD4
创建于:2019-05-30 有效至:永不 可用于:E
[ 绝对 ] (1). Mogeko <test@live.com>
gpg> addkey
然后选择子密钥的密钥类型,根据实际需求选择即可
请选择您要使用的密钥类型:
(3) DSA(仅用于签名)
(4) RSA(仅用于签名)
(5) ElGamal(仅用于加密)
(6) RSA(仅用于加密)
您的选择是? 4
选择密钥长度,同样的默认 2048
即可
RSA 密钥的长度应在 1024 位与 4096 位之间。
您想要使用的密钥长度?(2048) 2048
然后选择密钥有效期,这里不推荐默认选项 0
(永不过期),推荐使用选项 1y
(一年有效期)
请设定这个密钥的有效期限。
0 = 密钥永不过期
<n> = 密钥在 n 天后过期
<n>w = 密钥在 n 周后过期
<n>m = 密钥在 n 月后过期
<n>y = 密钥在 n 年后过期
密钥的有效期限是?(0) 1y
输入密钥的密码
然后确认一下密钥信息,然后输入 save
保存密钥
sec rsa2048/71C861745213C7DC
创建于:2019-05-30 有效至:永不 可用于:SC
信任度:绝对 有效性:绝对
ssb rsa2048/57440229D371DCD4
创建于:2019-05-30 有效至:永不 可用于:E
ssb rsa2048/8873AB36406A34F5
创建于:2019-05-30 有效至:2020-05-29 可用于:S
[ 绝对 ] (1). Mogeko <zhengjunyi@live.com>
gpg> save
然后 8873AB36406A34F5
就是我们的子密钥名称,同时也是子公钥,平常使用的公钥也是这个
导出密钥、子密钥和吊销证书🔗
现在,我们准备的两个 U 盘终于可以派上用场了。
将 U 盘格式化 (文件系统最好选择 fat32
,以保证最好的兼容性),然后将 U 盘挂载到虚拟机上 (如果使用了虚拟机的话),我这里将 0号U盘
挂载到了 /run/media/mogeko/USB0/
,将 1号U盘
挂载到了 /run/media/mogeko/USB1/
然后导出 GPG 的密钥、子密钥和吊销证书。
使用以下命令导出密钥到 0号U盘
,然后输入密码
gpg -o /run/media/mogeko/USB0/gpg_key --export-secret-keys 71C861745213C7DC
使用以下命令导出子密钥到 1号U盘
,同样需要输入密码
gpg -o /run/media/mogeko/USB1/gpg_key.sub --export-secret-subkeys 71C861745213C7DC
然后导出吊销证书,可以使用以下命令生成
gpg --generate-revocation 71C861745213C7DC
不过实际上在生成密匙时就已经生成了一份吊销证书了,放在这个目录下面 ~/.gnupg/openpgp-revocs.d/
,我们也可以直接将它移动到 0号U盘
mv ~/.gnupg/openpgp-revocs.d/2B452412DF8969D5682E279A71C861745213C7DC.rev /run/media/mogeko/USB0/revoke.rev
总结一下,现在 0号U盘
里有 gpg_key
和 revoke.rev
,现在 1号U盘
里有 gpg_key.sub
分别卸载两个U盘,然后将 0号U盘
保存到一个绝对安全的地方,例如银行的个人保险柜。
卸载密钥🔗
现在使用以下命令卸载刚刚生成的密钥
gpg --delete-secret-keys 71C861745213C7DC
然后清理吊销证书,将当前环境恢复到生成密钥前的样子。
如果是虚拟机的话就跟方便了,直接删除整个虚拟机。
为什么要卸载密钥呢?为了防止主密钥在使用过程中不小心被泄露,就像我刚刚说的:我们应该使用且只使用子密钥,主密钥应该放在一个绝对安全的地方。
导入子密钥🔗
在断网的环境下,将 1号U盘
插入到需要使用 GPG 的电脑上。
使用以下命令将子密钥导入到本地,并输入密码
$ gpg --import /run/media/mogeko/USB1/gpg_key.sub
gpg: 密钥 71C861745213C7DC:公钥 “Mogeko <zhengjunyi@live.com>” 已导入
gpg: 要迁移 ‘secring.gpg’,对每一张智能卡,执行:gpg --card-status
gpg: 密钥 71C861745213C7DC:私钥已导入
gpg: 处理的总数:1
gpg: 未改变:1
gpg: 读取的私钥:1
gpg: 导入的私钥:1
使用以下命令查看密钥
$ gpg -K
/home/mogeko/.gnupg/pubring.kbx
-------------------------------
sec# rsa2048 2019-05-30 [SC]
7E99AAF646B8B572979266C471C861745213C7DC
uid [ 未知 ] Mogeko <zhengjunyi@live.com>
ssb rsa2048 2019-05-30 [E]
ssb rsa2048 2019-05-30 [S] [有效至:2020-05-29]
sec
后面带 #
,表示我们安装的是子密钥,并且密钥不在本地。
这样就可以安心的使用了!
修改密钥的信任度🔗
因为我们的密钥是从 U 盘导入进来的,所以 GPG 对于这个密钥的信任度是未知。
我们可以使用 GPG 选项 --edit-key
+ 密钥名称
编辑密钥,修改 GPG 对密钥的信任度
$ gpg --edit-key 71C861745213C7DC
gpg (GnuPG) 2.2.15; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
私密子密钥可用。
pub rsa2048/71C861745213C7DC
创建于:2019-05-30 有效至:永不 可用于:SC
信任度:未知 有效性:未知
ssb rsa2048/57440229D371DCD4
创建于:2019-05-30 有效至:永不 可用于:E
ssb rsa2048/8873AB36406A34F5
创建于:2019-05-30 有效至:2020-05-29 可用于:S
[ 未知 ] (1). Mogeko <zhengjunyi@live.com>
gpg> trust
输入 GPG 命令 trust
,然后根据实际情况修改 GPG 对于密钥的信任度
pub rsa2048/71C861745213C7DC
创建于:2019-05-30 有效至:永不 可用于:SC
信任度:未知 有效性:未知
ssb rsa2048/57440229D371DCD4
创建于:2019-05-30 有效至:永不 可用于:E
ssb rsa2048/8873AB36406A34F5
创建于:2019-05-30 有效至:2020-05-29 可用于:S
[ 未知 ] (1). Mogeko <zhengjunyi@live.com>
请决定您对这名用户能否正确地验证其他用户密钥
(通过查看护照,检查不同来源的的指纹等等)的相信程度
1 = 我不知道或不作答
2 = 我不相信
3 = 我勉强相信
4 = 我完全相信
5 = 我绝对相信
m = 回到主菜单
您的决定是什么? 5
信任度修改之后,在重启程序之前,所显示的密钥有效性不一定正确
因为我们只是修改了 GPG 对密钥的信任度,并没有修改密钥的元数据,所以直接使用 quit
退出
pub rsa2048/71C861745213C7DC
创建于:2019-05-30 有效至:永不 可用于:SC
信任度:绝对 有效性:未知
ssb rsa2048/57440229D371DCD4
创建于:2019-05-30 有效至:永不 可用于:E
ssb rsa2048/8873AB36406A34F5
创建于:2019-05-30 有效至:2020-05-29 可用于:S
[ 未知 ] (1). Mogeko <zhengjunyi@live.com>
请注意,在您重启程序之前,所显示的密钥有效性不一定正确。
gpg> quit
发送公钥到公钥服务器🔗
将公钥发送到公钥服务器上,方便别人取用
$ gpg --send-keys 71C861745213C7DC
gpg: 正在发送密钥 71C861745213C7DC 到 hkps://hkps.pool.sks-keyservers.net