GPG公私钥的使用和Q&A

之前说送一些人我的签名,发现我没有 GPG 签名,写篇文章记录一下,网上相关简单操作挺多,详细说明挺少的,开个文章记录一下。

一、用途

使用公私钥加密的方式,命令行方便快捷,可以用于签名或者加密,密码学的基础使用。

二、简单操作

安装:brew install gpg 创建:gpg --full-generate-key (创建时会自带一个吊销证书,log 里会告诉你它的位置)

1
2
gpg: 密钥 8F61CA6F3EF1BD55 被标记为绝对信任
gpg: revocation certificate stored as '/Users/leadroyal/.gnupg/openpgp-revocs.d/335E7E6214DCA04AABD60CFF8F61CA6F3EF1BD55.rev'

将来使用8F61CA6F3EF1BD55 ,作为 GPG 钥匙串的唯一身份标识。

主动生成吊销证书:
gpg --armor --export [ID]

这里讲一下 ID 这个概念,ID 可以表示 sec(也就是masterKey)的 ID、ssb的 ID,通过ssb的 ID可以找到唯一的masterKey的 ID,但是通过 masterKey的 ID获取到的是多个ssb的 ID。可以是完整的很长的 ID,也可以是后面几位。

输出GPG 钥匙串的指纹(即哈希):
gpg --fingerprint [ID]

发布 GPG 钥匙串到互联网:
gpg --send-keys [ID]

随便发布到哪个 keyserver 都行,它们之间会相互同步消息的,默认的访问不到就换一个。

列出公钥:

gpg -kgpg --list-keys

列出私钥:

gpg -K 或者 gpg --list-secret-keys

删除私钥:
gpg --delete-secret-keys [ID]

删除公钥:

gpg --delete-keys [ID]

删除私钥和公钥:

gpg --delete-secret-and-public-keys [ID]

使用pubKey 进行加密:

gpg -e demo.txt

使用ssbKey 进行签名,有两种写法:

单文件格式:

gpg -u [ID] --sign demo.txt (文件不能太大)

分离格式:

gpg -u [ID] --detach-sign demo.txt

使用 ID1 的 pubKey 进行加密同时使用 ID2 的 priKey 进行签名:

gpg --local-user [ID1] --recipient [ID2] --armor --sign --encrypt demo.txt

解密:

gpg -d filename

验证签名:

gpg --verify filename

导入 (各种)key:

gpg --import filename

导出binary版本的pubKey:

gpg --export

导出 ASCII 版本的pubKey:

gpg -a --export

导出 ASCII 版本的ssbKey:

gpg -a --export-secret-subkey [ID]! 对于 ssbKey里有个感叹号

导出ASCII 版本的masterKey:【不要泄露它】

gpg -a --export-secret-key [ID]

三、Q&A

先说几个简称或者概念

masterKey:经常用 [sec] 标记,本质是私钥,可以用于签发ssbKey,可以用于签名文件。

ssbKey(secret subkey):经常用 [ssb] 标记,本质是私钥,可以用于签名文件和解密文件。

pubKey:经常用 [pub] 标记,本质是公钥,和masterKey是一对,可用于验证签名。

subKey:经常用 [sub] 标记,本质是公钥,和ssbKey一一对应,可用于验证签名和加密文件。

Q:[吊销证书/凭证]文件,是针对 masterKey 还是 ssbKey?

A:从用途上看,应该是针对masterKey的。因为在忘记主私钥的密码或者主私钥被泄露时,只有它才可以完成吊销,所以是针对 masterKey 的。而如果针对某个ssbKey的泄露,我们可以在gpg --edit-key [ID] 的界面里,主动对其进行吊销,然后在推送到服务器上。

Q:当masterKey被吊销后,会发生什么?

A:使用该 masterKey 已创建的、新创建的ssbKey均被吊销,全部信任均消除。

Q:为什么在搜索某人的 GPG-pubKey 时候,可以有不同的搜索方式?

A:例如输入邮箱可以搜到,这个很好理解;输入masterKey的 ID 也可以搜到;输入ssbKey的 ID 也可以搜到。ssbKey 是可以任意添加的,所以可以通过很多方式来搜到同一个账号。

Q:为什么网上下载回来某人的 pubKey,用它加密时候总是会弹出是否信任这个pubKey?

A:首先,防止误操作;其次,网络上发布的 pubKey(尤其是第三方平台),虽然比较可信,但也存在被恶意篡改的情况,所以默认应该是未知(Unknown)。对它的信任与否要用户手动设置,在gpg --edit-key [ID] 里主动设置trust等级。最后,发布公钥的人,在发布 ID 的同时一定要发布 hash,防止其他人拿错 pubKey,造成乌龙的现象。

Q:为什么我在签名、解密、导出ssbKey钥时候总是要输入密码?

A:假设masterKey 还在本地,使用 masterKey 的签名、签发功能,肯定要输入密码;假设仅拥有ssbKey,其实是可以修改密码的,因为 ssbKey 已经和masterKey脱离了联系,使用 passwd 将密码置空,即可让该ssbKey的签名/解密操作不输入密码。另一种表现,密码是用来保护某台计算机上的某个 GPG-Ring 的,包括 masterKey 和 ssbKey,在没有 masterKey 的情况下,留空的话也没什么大碍。

Q:多个ssbKey之间的关系是什么?

A:相互独立,keyA 加密的东西,keyB是无法解密的。

Q:ssbKey存在的意义是什么?

A:他们均归属于 masterKey,都有公信力,便于分发,而且泄露后可吊销。其实解密、签名这个操作可以由单个的 ssbKey 完成,而且确实是由他们完成的,masterKey 的用途是产生 ssbKey。 一般有一个 [E] 功能的ssbKey和 [S] 功能的ssbKey就够了。

Q:导出ssbKey时如果不输密码,也会导出,是为什么?

A:不输密码的话,导出的其实是个pubKey,虽然看到有文字,里面并不包含ssbKey。不信可以添加后gpg -K ,是不拥有ssbKey的。

TIPS:

在加密、签名时,是可以指定使用某个ssbKey的,一定要输入 [ID]+"!",感叹号做结尾,不然可能会使用其他的 key,例如下面这段:输入F1F74A9EA63EB5C7 时使用的是另一个叫E63D6C59D839E663 的ssbKey,而输入F1F74A9EA63EB5C7!时候才用F1F74A9EA63EB5C7这个ssbKey。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
➜  /tmp gpg -e demo.txt
您没有指定用户标识。(您可以在命令行中用“-r”指定)

当前收件人:

输入用户标识。以空白行结束:F1F74A9EA63EB5C7

当前收件人:
rsa2048/E63D6C59D839E663 2018-06-13 "AAAAA <B@C>"

输入用户标识。以空白行结束:F1F74A9EA63EB5C7!

当前收件人:
rsa2048/F1F74A9EA63EB5C7 2018-06-13 "AAAAA <B@C>"
rsa2048/E63D6C59D839E663 2018-06-13 "AAAAA <B@C>"

输入用户标识。以空白行结束:

Q:上文提到的 ID 可以是什么?

A:只要能够比较精准的找到目标 key 的东西,都可以作为 ID。 如果想找masterKey,可以是username、email,可以是ID的后半部分,可以是完整的 ID,可以是ssbKey的 ID。 如果想找ssbKey,只可以通过ID的后半部分和完整的 ID 来找。

TIPS:

记得经常加 --expert 参数,例如gpg --expert --edit-key [ID] 就可以使用一些高级设置了。

Q:为什么我 gpg -k 和 gpg -K不会输出ID 呢?

A:可能需要加上 --keyid-format short/long/0xshort/oxlong