上篇链接:

2021年,用更古代的办法应用PGP(上)
2021年,用更古代的办法应用PGP(中)

PGP 公钥的 公布 与 替换

探讨公钥平安替换的中文文章比拟少,而这一环是整个加密体系的重中之重。 大部分的PGP教程最初一步就是让小白用户将公钥上传,这是十分过期,且不负责任的,所以这里来具体介绍下PGP 公钥的 公布 与 替换。

准则

首先明确一点: 上传公钥到 公钥服务器 不是必要的,甚至是危险的。

如果你是老手,请不要公布你的公钥到 公钥服务器。

引子

通过前文,你曾经相熟了gpg的本地应用, 并且生成了本人的PGP 密钥对。

设想一下, 如果你生存在1980年代, 想和远方的敌人加密通信,须要先替换彼此的公钥,又没有一个对立的可信的认证机构,这时会有什么问题?

当面替换吗?当然是个方法,然而置信你不会想要将下列

这么长的公钥缮写到纸上,而后开车送到敌人那里,再让敌人照着这个输出他的电脑。如果两头有变动,须要反复以上过程n次。

那么还有其余方法吗?

那个时代还没有line、wechat这类即时通讯软件,而邮件提供商默认是不牢靠的,不然也不会有PGP的诞生。 并且彼时https还未呈现,用邮件替换PGP替换公钥显然不太平安。

你们单方都须要便捷地替换公玥, 并且确认彼此失去的公钥的确是未经篡改过的,真实有效的,就成了一个难题,这样,公钥服务器也就跃然纸上了。

公钥服务器 KeyServer

公钥服务器使得人们只须要替换他们短短的key id 或者user id就能够不便地从公钥服务器下载公钥。

历史与设计初衷

第一个KeyServer 叫做 HKP( web-based OpenPGP HTTP Keyserver Protocol) Keyserver , 诞生在上世纪90年代,是Marc Horowitz在麻省理工学习时为了他的论文而搭建的。在此之前, 尽管不是那么平安, 然而大部分人依附电子邮件来替换公钥。

尽管服务器有了, 但开发者们放心政府会试图强制钥匙服务器运营商用政府抉择的各种证书来替换证书。

所以他们做出了一个决定:公钥服务器永远不会删除信息。公钥服务器能够为现有的证书增加信息(比方能够revoke/sign或者调整expire工夫),但永远永远永远不会删除证书或证书的信息。

为了达到这个指标,他们开始运行一个分布式的国内公钥服务器网络,这就是当初的KeyServer。世界各地的公钥服务器会定期互相通信,同步,比拟目录。如果政府强制公钥服务器运营商删除或批改证书,那么在比拟步骤中就会被发现。完好的公钥服务器会用完整钥匙服务器目录中的内容更新本人。

任何货色都不会被删除,听起来很美妙,也是解决政府审查问题的一个简略而无效的方法,可是正是这个准则起初给KeyServer带来了无穷无尽的问题。

信赖网络 (Web of Trust)

好了,当初咱们有了一个能够不便地上传和下载公钥的中央, 这样是不是就高枕无忧了呢?

对于KeyServer 来说,任何人都能够上传公钥并宣称本人是Linus, 是Zuckerberg,或是任何其他人,而KeyServer并不会去验证你是否是你所宣称的人(因为KeyServer原本就没有一个中心化的运营者)。

如果你有一些密码学的根底, 那么就会晓得, PGP协定依附的非对称加密算法, 最软弱的点就在于公钥的替换这一步。公钥替换时最容易收到中间人攻打,你肯定要确定你接管到的公钥的确是你想交换的人的,由此TSL引入了CA证书认证体系,由一个可信的权威第三方来认证并颁发证书来解决身份的认证问题。 (具体可参见https系列没那么浅地谈谈HTTP与HTTPS)。

“信赖一个权威的第三方” 对于最后的极具备hack精力的开发者们来说, 显然是无奈承受的。

当然,你能够说下载公钥后,通过电话等伎俩验证下公钥的指纹(fingerprint),就能够确认正确与否。 然而设想一下, 如果你在公钥服务器找到一个宣称本人Linus Torvalds 的人, 你并没有他的其余联系方式,将永远无奈确定这个公钥持有者到底是谁、这个公钥可信与否 , 这样无疑是低效的,并且使整个零碎沦为了熟人之间的小网络。

要晓得,依据六度分隔实践(Six Degrees of Separation),世界上任何互不相识的两人,均匀通过六个人就能够产生分割。 那么能够不能够这么思考, 假如我和小A见过面并查看过他的公钥,因此晓得小A的公钥的的确确属于他自己,我抉择信赖小A。而小A同样验证了小B的证书并为小B的证书签名背书——小A的证书的持有人在此证实该证书是实在属于小B。那么我毋庸见亲见小B自己,也能够通过小A的背书而承受小B的证书。

如此循环上来,就造成了一张网, 这就是信赖网络。

支流公钥服务器

1. SKS Keyserver Pool

当今世界最大的Key Server 池, 合乎它的规范的世界各地的公钥服务器会定期互相通信,同步,比拟目录,数据齐全凋谢下载。 当初个别说起KeyServer说的就是这个。

KeyServer尽管始终是PGP的重要根底设置 ,但SKS Keyserver Pool 其实目前只有不到20台服务器,GnuPG默认用的服务器是其中的 HKPS pool,只有四台服务器。

2. Base Modern Software KeyServer

有一些KeyServer 没有用SKS的软件,运行的是更下古代和稳固的软件,比拟有代表性的是 Ubuntu keyserver, 基于Hockeypuck , 这些服务器依然会和SKS pool放弃同步。

3. 独立KeyServer

这些服务器不与SKS pool同步数据,由中心化的运营者运行, 会对公钥上传者做肯定的认证, 并且反对删除本人的公钥。

比拟有代表性的有, keys.openpgp.org ,KeyBase等等。

在gpg中应用

公布

gpg   --send-keys  {keyid/uid}

下载

gpg --recv-keys {keyid/uid}

此时有可能报错

gpg: "xxxxxr" not a key ID: skipping

这时换个KeyServer就行:

gpg  --keyserver hkps://keyserver.ubuntu.com --recv-keys {keyid/uid}

签名和验证 别人公钥

验证公钥真实性 依附多渠道确认的 公钥指纹。

一般来说为他人的公钥签名后,须要发还给他,或者发到公钥服务器(最好通过自己批准)。

gpg --sign-key  {keyid/uid}   # 为曾经导入的 别人钥签名, 你为他签名,意味着你将为他的身份真实性背书,请审慎 

高级设置

因为并不举荐大家应用KeyServer,所以这里只列举了根底操作。

如果你决定应用KeyServer的话,能够参考 OpenPGP 最佳实际 - 密钥服务器设置你的客户端与服务器通信应用 HKPS (HKP On SSL)协定, 并定期更新从服务器下载的公钥。

平安危险和争议, 被玩坏的KeyServer

在20世纪90年代初,开发者们怀着对技术的信念和兽性的心愿,冀望创立一个友善 、纯正、没有审查的净土, 在过后背景下,KeyServer不能删除任何已上传的货色,听起来是美妙的,设计仿佛是正当的。

然而事实是,网络匿名环境中充斥了不那么敌对的, 甚至是歹意的使用者,在当今看来 ,KeyServer这个零碎并不强壮,问题重重,许多问题曾经被发现十多年,而且有望解决。

滥用

依照官网举荐, UID (User ID) 是用来存储用户信息的,应该在外面填上你的名字和邮箱,一个 GPG 帐号下能够有若干个 UID。

而其实这个UID是没有任何强制限度的,也就是说你能够在UID中放入任何货色,能够是小说片段,能够是磁力链接,可是以编码后的图像、音频或视频......

当上传到KeyServer时, UID限度了2k的字符 . 以至于有人写了个用KeyServer存文件的我的项目keyserver-fs)。

再次设想一下,你往网盘传了一个文件,共享给其他人,全世界的人都能够往这个网盘文件中增加文件,而且永远无奈删除,状况会变得有多蹩脚。

软弱的KeyID

见过一些生成 PGP“靓号”的工具,就是指定你喜爱的ID规定,工具会暴力生成PGP密钥, 从中返回给你想要的密钥。

由此很容易想到,若攻击者晓得了指标的KeyID, 齐全能够通过工具来生成齐全一样的KeyID(这就是碰撞), 并上传到KeyServer,来假冒指标。

而伪造一个KeyID有多容易呢,有钻研人员借助scallion程序,应用了一般的GPU(Nvidia GeForce GTX)进行碰撞,花了4秒的工夫就生成了一个指定的32 bit的 KeyID。

官网举荐颁布本人的KeyID时,起码应该颁布64 bit(也就是长16位16进制数啦 ),然而钻研表明64 bit的KeyID也是能够 被碰撞的。

投毒

公钥服务器任何人都能够上传公钥,甚至你能够上传他人的公钥,比方你能够将本人签名过的他人的公钥,再次上传到KeyServer。

签名Dos

在WOT认证体系的设计中, 当客户端收到一份未知证书时,它该当从公钥服务器拉取所有为这张证书签过名的人的证书,逐层上溯,看看是否可能找到一张曾经被用户信赖的证书。如果能的话,就视信赖这张为可信的。

2019年6月,有攻击者歹意向公钥服务器提交了对两个驰名网友的签名背书。此事件中的受害者 Robert J. Hansen 的证书就被签名了 15000 次。因此任何人的 GPG 在尝试验证他的证书时,都会拉取 15000 个签名。而 GPG 在验证这么多签名的过程中会卡住很久。

因为被攻打的两个人在 GPG 社区中中位置很高,他们在 GPG 信赖网络中处于相当外围的地位。这意味着——当你验证任意一份证书的时候,有不小的概率你会不小心拉取到他们俩的证书,而后你的 GPG 就会卡住。岂但他们俩的证书没法用了,他们俩签名过的证书也都面临危险,乃至于他们俩签名过的证书所签名的证书……

而上传到KeyServer的所有货色都是不可删除的...为了解决这个问题, GnuPG 2.2.17 LWN.net 开始, 从KeyServer下载公钥时默认不再下载关联的公钥, 如果你想要感触证书DoS攻打的话,能够在设置中开启:

# ~/.gnupg/gpg.confkeyserver-options no-self-sigs-only,no-import-clean
爆破

有个很厉害的程序媛Yegor Timoshenko(后面的SKS文件存储我的项目也是她的杰作),写了个工具SKS-Exploit,能够将任何人的PGP公钥损坏,变得不可导入。

这个工具同时还能够给任意人的公钥 追加伪造的UID(不是KeyID),并骗过KeyServer。

另外能间接让KeyServer宕机。

隐衷问题

讥刺的是, 最后为了爱护人们隐衷而生的PGP , 却因为不能满足爱护隐衷的法规GDPR ,而使一个公开的 SKS 公钥服务器在欧洲处于守法状态(GDPR规定: 服务商必须提供删除个人信息的选项)。

许多老手依照教程提醒的在创立PGP 密钥的时候填上了本人的实在姓名,并依照那些教程将公钥上传到了KeyServer,在人肉社工猖狂的明天,几乎是个劫难。

我试着在KeyServer搜过一些博客作者留下的PGP Key, 不乏有些比拟重视本身隐衷的,可是他们大部分都将本人实在的名字(汉字或拼音)和邮箱一起发到了服务器上,要晓得那里的数据是公开且永远不能删除的。 也有些人意识到问题之后revoke了带有实在姓名的公钥,可是依然能够查到,并且变得更加显眼(revoke过的key会变红)。

其余公布公钥的办法

1. WKD(Web Key Directory)

WKD 的工作过程是 ,通过邮箱客户端 在域名服务器查看一个"well known" 的URL, 如果匹配到了邮箱地址对应的公钥,会应用https下载,并且不须要用户进行其余操作。用户不须要gpg 命令行等等简单操作,让PGP加密回归单纯的邮件加密自身,用起来有些像S/MIME,但其实不一样。

比方这样一个URL: https://intevation.de/.well-known/openPGPkey/hu/g8td9rsyatrazsoiho37j9n3g5ypp34h 就对应 "aheinecke@intevation.de"这个邮箱地址。

这是通过Gpg4win的应用的一个示例,

](https://files.intevation.de/u...

这种办法不会泄露本人的邮箱,也不须要验证指纹, 然而须要你的邮件服务商提供反对。

proton邮箱是原生反对 WKD的, 然而它应用的是本人私钥,仿佛没方法应用应用本人本地的公钥,其余也有反对。

如果你有本人的邮箱服务器,并且想折腾的话,能够参照WKD Hosting。

2. 当面替换

如果是和熟识的敌人,你能够约在任何适合中央,用你喜爱的形式替换密钥, 比方替换纸条,替换TF卡 或者usb设施,相互签名认证,相互失去公钥。

如果是想意识更多的人,并让本人的公钥被更多的人认证, 你能够加入「公钥签名派对(Key signing party)」。参加派对的人们相互交换公钥的指纹(公钥个别是存在服务器或是一个他人能够下载到的中央,这里只替换指纹),甚至须要互相出示身份证、护照、驾照、出身证实,以验明正身。

3. DNS

有很多种办法将你的公钥通过DNS服务公布,然而有些一些办法只实用于老版本的GnuPG,有些办法只实用与新版本的GnuPG,兼容性不佳,而且搞起来比拟繁琐,有趣味的能够自行查找材料。在这里并不举荐应用。

4.集体网站 或 社交软件中

当初中文世界, PGP的使用者中 有很多都是 独立的博客作者, 如果你领有本人的博客或者集体网站,当然能够抉择将本人的公钥公布在下面,最好给你的网站上一个Https 。

很多社交网站的集体展现页,能够自在编辑你的信息,你能够将PGP的 公钥公布在这里, 或者将 指纹 放在这, 这样通过其余渠道下载到公钥的人,也能够确认身份。

5. 代码仓库或Gist

无论你是不是开发者, 都能够领有一个Github账号, 你能够开一个仓库专门用来公布本人的公钥,或者将公钥公布到Gist。

6. 共享笔记

Notion或者印象笔记等能够共享笔记的中央,都能够贴出你的公钥。

最初

应用扩散的、多渠道的、可能是线下的形式来替换和确认公钥 ,不要置信在放一处的 公钥 和指纹。

去验证紧跟在公钥前面的指纹 , 就像你去问一个诈骗者,他是不是一个诈骗者一样无用。

如果不是当面,请至多从两个渠道进行验证,比方你从一个渠道(比方这里)失去了我的公钥 , 你想和我平安通信的话,导入前肯定要从另一处(比方我颁布的其余账号的简介)失去我的指纹, 验证是否统一后再进行操作。

而且每次应用前,请反复以上步骤,确保你手上的公钥是最新的。

参考链接

[1]. 用 PGP 爱护代码完整性系列

[2]. The GNU Privacy Handbook

[2]. GnuPG: 用多个sub keys爱护primary key | missing idea (wordpress.com)

[3]. PGP 自我扫盲

[4]. GPG 的正确应用姿态

[5]. 电子邮件加密指南

[6]. Short key IDs are bad news (with OpenPGP and GNU Privacy Guard)

[7]. gnupg密钥签订原理和过程 // Shell's Home (shell909090.org)

[8]. PGP Key Server| Roll Your Own Network

[9]. Are SKS keyservers safe? Do we need them?

[10]. SKS Keyserver Network Under Attack

[11]. OpenPGP 最佳实际 - 公钥服务器

[12]. GPG SKS 同步网络被投毒事件及其影响

[13]. where-to-upload-PGP-public-key-are-keyservers-still-surviving

[14]. GPG扼要介绍