乐趣区

关于加密:2021年用更现代的方法使用PGP下

上篇链接:

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.conf
keyserver-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 扼要介绍

退出移动版