PGP 与 GPG 是啥关系?
我们这里简化概念,你只需要了解这几点就好了:
- GPG
-
- 就是 GnuPG 就是 GNU Privacy Guard,是一款自由软件。
- 我们用它完成各种具体操作:生成密钥对、签名/验证、加密/解密。
- OpenPGP
-
- 是一套开放的互联网标准。
- GPG 是这套标准的实现。
- OpenPGP 有一套信任体系:Web of Trust(信任之网)。
- OpenPGP 有一套开放的公钥服务器池:SKS Keyservers,用户可以自由上传自己的公钥。
如今最早的商业软件 PGP(Pretty Good Privacy)只活在维基百科中,几乎所有 PGP 都指的是 OpenPGP。你知道就行,我们不咬文嚼字。
细节
GPG 的吊销证书
如果你的 SSH 登录私钥丢了,你只需要告诉对应服务器就行了,让服务器删除相应公钥。
除非你的组织要求很严格,否则你应该不太想在 SSH 上倒腾有效期、吊销证书、短期证书这些问题。
而 GPG 的公钥因为需要被广为人知,所以一旦私钥丢了就很麻烦,得通知所有人“我这个公钥不能信了”。
因此 GPG 多了一个“吊销证书”(revocation certificate),拿着这个证书你就能证明“我就是我,我的身份证丢了,你们赶紧把丢了的那个作废”。
而其他人呢,看到你在原来的证书基础之上,又发布了这么一张吊销证书,就知道原来的证书已经不可信了。
GPG 的过期时间
GPG 密钥对(key pair)可以设置“过期时间”,也可以永久有效,你可以随便设置。
当你发布公钥的时候,里面就包含了过期时间信息。
别人也就知道,在这个时间过后,该证书的签名是无效的。
很多人会选择一个懒人方案:给主密钥设置一个很长的过期时间,给子密钥设置一个较短的过期时间。
GPG 的子密钥
GPG 非常明智地设计了 subkey 机制,让用户免去给自己设计证书信任链的麻烦。
我们来看个例子:
- 主私钥必须有【认证 [C]】这个能力,且这项能力只能属于主私钥。
- 主私钥可以同时拥有【认证 [C]】、【签名 [S]】、【身份验证 [A]】三项能力。
- 子私钥可以同时拥有【签名 [S]】、【身份验证 [A]】两项能力。不能拥有认证 [C] 能力。
- 【加密 [E]】能力必须属于独立的子私钥,因为加密用的是不同的算法变体(和签名不一样)。
看到这里你可能已经明白了,一个 GPG 密钥对之所以可以有这么多能力,是因为它本质上是若干密钥对的集合,只不过它们被封装到了一起。
所有子密钥的有效性,都来自于主密钥的认证。
子密钥可以在没有主密钥的情况下单独使用。
子密钥的公钥
你可能会奇怪,这些子密钥的公钥呢?
实际上子密钥的公钥是存在的,也可以导出,但 GPG 为了防止用户误用,把这项功能藏得很深。
毕竟,如果子密钥的公钥也单独使用,那就跟自己设计一个证书信任链没什么区别了。
我们在实际使用中,导出的“公钥”实际上是一组公钥,其中就包括了被主私钥【认证 [C]】后的各个子公钥。信任关系很明确,不是吗?
单一公钥机制对于服务端的验证特别友好,无论用户有多少个子密钥,服务器只需要一份证书(公钥)就够了,而不需要额外开销,去查询这份证书是哪个上级签发的。
比如 GitHub、GitLab 的 GPG 功能,就只认用户上传的 GPG 公钥,而不从任何信任体系中获取上级证书。
子密钥的吊销
从图中可以看出来,整个“密钥串”只有一张吊销证书,一旦这张证书发布,主密钥即被吊销,连带着子密钥一并吊销。
那子密钥丢失了怎么办呢?
GPG 不允许用户生成子密钥的吊销证书,而是把变更都放在唯一的公钥中,简洁且不易出错。
你只需要编辑“大”密钥,将子密钥单独吊销,然后重新发布公钥即可,这样大家就都知道了。
GPG 的用户身份(UID)
uid 即 user id
一个 uid 由三个部分组成:
- 全名(一般是实名)
- 注释(用 ( ) 包括)
- 邮箱地址(用 < > 包括)
这三个部分都是可选的,只要有一项即可。
例如:
Han Meimei email@example.com
Han Meimei (Work) hanmm@company.com
Han Meimei (Product) hanmm@company.com
- 一个密钥可以有多个 uid,方便不同场合使用。
- uid 与哪个子密钥无关,uid 是作用于整个密钥的。
- uid 可以随时添加,但已有的 uid 不能修改,只能单独吊销。
- uid 单独吊销后,只需要重新发布公钥即可。
如果你希望只用一个密钥,但某些身份不公开,你需要小心配置你的公钥,不过最好还是另外用一个密钥。
概念对比
同义词
证书 = 公钥
指纹 = 摘要 = 哈希值 = 杂凑值
密钥能力 = 密钥用途
GPG 与 SSH
-
SSH (Secure Shell) 用于交互通信过程中的安全,是双向的。
-
GPG (GNU Privacy Guard) 既可用于加密,也可用于签名,这些都是单向的。
-
私钥在 SSH 中被称为 private key,而在 GPG 中被称为 secret key。
-
公钥则都叫 public key。
-
一般来讲,SSH 的公钥只有你的服务器知道,别人也不需要知道。
-
GPG 的公钥就不一样了,巴不得全世界知道,告诉大家“认准这个证书,谨防假冒!”
-
对于 SSH,建议一站一钥,万一丢了也好处理。
-
对于 GPG,一把主钥+多个子钥即可。
-
如果你明白了 GPG 的多用途,完全可以把 GPG 的子密钥 [A] 用于 SSH 登录。
SSH 虽然用起来简单,但毕竟是安全通信,实际发生的登录过程并不简单:
- 对称加密算法的性能,比非对称加密算法高很多,因此通信的主要内容,还是要用对称加密。
- 对称加密需要双方使用相同的密码,如何在不告诉对方密码的前提下,互相使用一样的密码(会话密钥),就要用到密钥交换算法。
- 在折腾完这一通,建立起安全通信后,才开始互相的身份验证。首先是用户拿手里的服务器公钥,验验服务器是不是真货。
- 用户第一次连接服务器时,手里没有服务器的公钥,因此客户端会问用户要不要信任服务器发来的公钥。这是经典的中间人攻击切入点。
- 到现在用户的 SSH 私钥才派上用场,服务器拿它手里的用户公钥,验验用户是不是本尊,完成登录。
- 即使登录上了,双方也会时不时更换会话密钥,保证通信的安全性。
GPG 与 TLS
TLS 基于“集中式”的信任链,它依赖于操作系统出厂内置的【根证书】,用户默认信任根证书,因此才能信任根证书签发的二级、三级证书(公钥)。
要给网站启用 HTTPS 流量加密,我们需要先【申请】 TLS/SSL 证书,这本质上是请求签发机构【信任】你。用户信任你的上级单位 → 上级单位信任你 → 用户信任你。
GPG 并不搞集中式,虽然开源世界中有不少 GPG 公共服务器组成的【公钥服务器池】(Web of Trust),但 GPG 将信任与否的决定权交给用户。
当然,你也可以把自己的公钥上传到服务器池,方便他人悉知。
引用 依云 的一句话:
bbs.archlinuxcn.org/viewtopic.p…
世界上有两种密钥信任体系,PGP 的 web of trust 和 TLS 证书的 CA。前者是社交化的,相信你所相信的人。后者是相信权威。
本文参考:
zhuanlan.zhihu.com/p/137801979
如果你喜欢我的文章,请关注我的微信公众号 deliverit。