「译」PGP的问题(上)

问题

Posted by UlyC on September 5, 2022

「译」PGP的问题(上)– 问题

原文链接 ,原作者为 Latacora,一个国外安全团队。

几十年来(一点不夸张地),密码学工程师们一直为PGG的缺陷 困扰得拽头发。

当其他领域的工程师得知这个消息时, 他们会感到震惊 。啥? PGP不行? 那为啥人们总是告诉我用PGP?

答案是他们不应该告诉你, 因为PGP就是不行, 需要被淘汰。

正如你将要看到的,PGP有非常多的问题。

幸运的是, 如果你并不是病态地好奇, 它有一个简单的元问题:它是20世纪90年代设计的,在严肃的现代密码学诞生之前。

(如今)没有一个合格的密码工程师会设计一个像今天的PGP一样的系统, 也不会容忍它在其他设计中的大部分缺陷。

严肃的密码学家们在很大程度上已经放弃了PGP, 并不再花时间为它发表论文(有一个明显的例外)。

由于这个原因,PGP中被充分理解的问题已经有十多年没有得到解决了。

有两点要注意:: 第一, 我们这篇文章是为工程师写的, 不是为律师和活动家写的。

第二, “PGP “可以指一堆东西,从OpenPGP标准到GnuPG的参考实现。我们用 “PGP “这个词来涵盖所有这些东西

问题

荒谬的复杂性

由于一些我们这些未来人都不理解的原因, PGP有一个基于数据包的结构。

PGP 信息(包含在“.asc”文件中)是类型化数据包的存档。 根据您使用的是“新”还是“旧”格式的数据包,至少有 8 种不同的方法可以对数据包的长度进行编码。

新格式的数据包长度是可变的,如 BER(尝试编写 PGP 实现,您可能会希望 ASN.1 的sweet release)。包可以有子包。某些数据包有重叠的变体。

最近发生的公钥服务器攻击是因为 GnuPG在解析密钥时意外出现指数级增长,这也是遵循这种发癫的格式。

以上只是编码的问题。

实际用起来的时候,系统并不会更简单: 有主密钥和子密钥,密钥ID、公钥服务器和密钥签名,只有签名的和只有加密的,多个 “密钥环”,撤销证书,三种不同的压缩格式。

这些还都是在我们谈到智能卡支持之前。

瑞士军刀式的设计

如果你被困在森林里里,我不清楚,需要修理你的牛仔裤袖口,如果你的多功能刀有一把剪刀,那就很方便了。但是,没有一个做正经工作的人经常使用他们的多功能刀的剪刀。

一把瑞士军刀能做一堆事情,但都做得很差:

  • PGP在签名方面做得很平庸
  • 在用密码加密方面做得相对较差
  • 在用公钥加密方面做得相当糟糕
  • PGP并不是一个安全传输文件的好方
  • 它是一个笨拙的签名包的方式
  • 它在保护备份方面不是很好
  • 它是一种完全危险的安全信息交流方式

回到 PGP 起源的 MC Hammer 时代,“加密”只是“一件”特殊的事: 有一个工具用来(单纯地)发送文件,或只是备份一个目录,又用另外的工具来加密和签名文件。

而现代密码学不是这样运行的, (不同加密算法)有其专门的目的。 例如,安全地传递消息也需要加密,一种不同于安全备份或包签名的加密。

陷入兼容旧版的泥潭

PGP 早于现代密码学;比Hanson的专辑还要久远的年代。

如果幸运的话,您的本地 GnuPG 默认为 2048 位 RSA、CFB 中的 64 位块 CAST5 密码和 OpenPGP MDC 校验和(稍后会详细介绍)。

如果您使用密码而不是公钥进行加密,OpenPGP 协议会指定了PGP 的 S2K 密码 KDF。委婉地说,这些不是密码工程师为现代系统选择的原语。

自从 Steve Urkel 在 ABC 的 TGIF 节目中出现以来,我们学到了很多:

  • 你应该验证你的密文(并避免 CFB 模式)将是一个明显的例子。
  • 64 位分组密码并不好,我们可以做很多比 RSA 更好的事。
  • 混合压缩和加密是危险的,而且 KDF 应该是时间和内存困难的。

无论 OpenPGP RFC 怎么说,如果您使用 PGP,您可能不会做任何这些事情,也无法预测何时会做。

以 AEAD 密码为例:Rust 语言的 Sequoia PGP 默认为 AES-EAX AEAD 模式,这很好,没有人可以阅读这些消息。 而因为大多数 PGP 安装者并不知道 EAX 模式是什么,这就不太好了。

每个众所周知的坏密码系统最终都会产生一个支持曲线或 AEAD 的 RFC 扩展,以便其支持者可以在留言板上声称他们支持现代密码学。

RFC 无关紧要:只有安装PGP的这些基本盘才重要。

我们已经搞了认证加密这一套20 年了,PGP 已经足够成熟了,它都能自己去超市给我买酒了。(抱歉

您可以选择兼容 1990 年代的旧版本,也可以选择拥有健全的密码学。 但你并不能同时拥有

令人讨厌的用户体验

我们不能说得比 Ted Unangst 更好了:

几年前进行了一项 PGP 可用性研究,其中一组技术人员被安置在一个有计算机的房间里,并要求设置 PGP。 两个小时后,这些人没了,消失了,杳无音讯

如果您想要自己的经验数据来支持这一点,您可以进行以下实验:

  1. 找到一位移民律师,并与他们讨论让 Signal 在他们的手机上工作的过程
  2. 你可能不会马上体验到它的美味
  3. 现在尝试(把Signal换成) PGP 来做这件事

长期的密钥

PGP 请求用户保留与他们的身份相关联的几乎永久的根密钥。

它通过使 密钥生成和交换变得烦人、“密钥签署Party” , 以及创建一个 “信任网”(Web Of Trust), 使密钥依赖于其他密钥 ,来做到这一点。

长期密钥几乎从来都不是您想要的。如果您持续地使用密钥,它最终都会泄漏。

您希望妥协的爆炸半径尽可能小,而且同样重要的是,你不希望用户在对他们目前的密钥的安全有任何担心的情况下, 对启用新密钥的想法有任何犹豫。

PGP 氛围组马上就会回复:

“这就是为什么你要把密钥放在 Yubikey里~”

大致上来说,全世界没有人使用昂贵的 Yubikey 来做这个,而且你也别期待未来会发生。 (我们连U2F的推广都进行不动,而且这些密钥是一次性的)。

我们不能仅仅为了让 Unix 书呆子对他们的玩具感觉更好,而接受糟糕的密码系统。

身份验证的崩溃

更多关于 PGP 的古老原语:早在 2000 年,OpenPGP 工作组就意识到他们需要对密文进行身份验证,而 PGP 的签名并没有做到这一点。

因此 OpenPGP 发明了 MDC 系统:带有 MDC 的 PGP 消息将明文的 SHA-1 附加到明文,然后在 CFB 模式下加密(跟平常那样)。

如果您想知道当现代系统使用相对复杂的 AEAD 模式时 PGP 如何解决这个问题(为什么每个人都不能将 SHA-1 添加到他们的明文中),您并不孤单。

从哪里开始使用这个 Rube Goldberg 装置呢?PGP MDC 可以被剥离消息——它的编码方式是你可以简单地截掉密文的最后 22 个字节来做到这一点。

为了保持与不安全的旧信息的兼容性,PGP 引入了一种新的数据包类型来表示需要验证 MDC;如果您使用了错误的类型,则不会检查 MDC。

即使您这样做了,新的 SEIP 数据包格式也与不安全的 SE 格式非常接近,可能会诱使读取方降级;Trevor Perrin 将 SEIP 设计为 16 个完整的安全位

最后,即使一切顺利,Reference的PGP 实现也会(等待它)向调用者发送未经身份验证的明文,即使 MDC 不匹配

不连贯的身份

PGP 是一个应用程序 它是与其他应用程序的一组集成 它是一种文件格式 它也是一个社交网络 也是一种亚文化。

PGP 推动了加密身份的概念:

  • 您生成一个密钥,将其保存在您的密钥环中,在您的名片上打印其指纹,然后将其发布到密钥服务器。
  • 你在别人的密钥上签名。
  • 他们反过来可能会也可能不会依赖您的签名来验证其他密钥。
  • 有些人会特意亲自与其他 PGP 用户会面,以交换密钥并更安全地连接到这个“信任网络”。
  • 还有一些人会组织“密钥签署Party”。

您现在在脑海中勾勒出的图像准确地解释了 PGP 的拥护者们切换到更新的东西有多难。

不过这种黏在一起的身份没啥用。

普通人会相信任何看起来像 PGP 密钥的东西,而不是密钥签名信任网络,不是密钥服务器,不是那些Party ,无论它来自哪儿——他们怎么可能不信? 即使是专家也很难阐明如何评估密钥。

专家不信任他们没有亲自交换过的密钥。其他所有的人都依赖一个中心化的机构来分发密钥。 PGP 的密钥分发机制是场闹剧。

泄露元数据

先不说电子邮件的问题(我们稍后会说到), PGP本身就泄露了元数据。

信息(在正常使用情况下)直接与密钥标识符相连,而密钥标识符在整个PGP的信任网中与用户身份相连。

此外, 很大一部分PGP用户使用密钥服务器,这些密钥服务器本身也会向网络泄露哪些PGP用户正在相互通信的身份。

无前向保密性

PGP的最后一个问题,有一个很好的例子:安全消息传递加密要求前向保密。

前向保密意味着,如果你今天向攻击者“Say Hi”,并丢了一只密钥,他们仍然不能去阅读到昨天的消息;他们必须在昨天带着密钥在那里才能阅读它们。

在现代密码学工程中,我们假设我们的对手正在将所有内容记录到无限存储中。PGP 声称的对手包括世界各国政府,其中许多政府确实在这样做。针对强大的对手并且没有前向保密,被破解是“何时”的问题,而不是“如果”的问题。

为了在实践中实现保密,您通常会保留两个密钥:一个短期会话密钥和一个长期可信密钥。 会话密钥是临时的(通常是 DH 交换的产物)并且受信任的密钥对其进行签名,因此中间人无法交换自己的密钥。

理论上,使用PGP提供的工具可以实现前向保密的雏形。当然,几乎没有人这样做。

笨拙的密钥

OpenBSD的 signify(1) 公钥是一个 Base64 字符串,短到可以放在电子邮件的句子中间;如果是私钥,不是交换格式,只比公钥长了一行左右。

PGP 公钥是一个巨大的 Base64 文档;如果您经常使用它们,那么您可能已经习惯于将它们添加到附件,而不是将它们粘贴到消息中,这样它们就不会被损坏。

Signify 的密钥是最先进的 Ed25519 密钥;PGP 是较弱的 RSA 密钥。

您可能认为这些东西无关紧要,但它很重要;使用 SSH 和管理 SSH 密钥的人比使用 PGP 的人多几个数量级。SSH 密钥处理起来很简单,而PGP 不是。

协商

PGP 支持 ElGamal。PGP 支持 RSA。PGP 支持 NIST P 曲线。PGP 支持 Brainpool。PGP 支持 Curve25519。PGP 支持 SHA-1。PGP 支持 SHA-2。PGP 支持 RIPEMD160。PGP 支持 IDEA。PGP 支持 3DES。PGP 支持 CAST5。PGP 支持 AES。这不可能是 PGP 支持的完整列表。

如果我们在过去 20 年中学到了关于密码学设计的 3 件重要的事情,其中至少 2 件是协商和兼容性是恶魔。密码系统中的缺陷往往出现在细枝末节中,而不是主干上,而广泛的密码兼容性增加了细节的数量。

像 TLS 1.3 这样的现代协议正在抛弃与 RSA 等东西的兼容性,而不是添加它。新系统只支持一套原语 和一个简单的版本号。如果这些原语之一失败,您会立即更改版本并放弃旧协议。

如果我们不走运,20 年后人们仍在使用 PGP,那么 PGP 将是任何地方的任何代码会包含 CAST5 的唯一原因。

我们不能说得再清楚或者再啰嗦了:您可以选择兼容 1990 年代的旧版本,也可以选择拥有健全的密码学。 但你并不能同时拥有

简陋的代码

PGP 的实际标准实现是 GnuPG。GnuPG 不是精心构建的。

这是一个庞大的 C 语言代码库,具有重复的功能(例如,最近的 SKS 密钥解析DoS的记录指出它有多个密钥解析器)具有从内存损坏 到加密侧信道的 CVE 的长期跟踪记录

有时可以在 GnuPG 不注意的情况下将身份验证器从消息中剥离。有可能在它没有注意到的情况下向它提供没有正确指纹的密钥。2018 Efail 漏洞是因为它向调用者发布未经身份验证的明文。

GnuPG 就是不行。

GnuPG 也是 PGP 的有效参考实现,也是集成 PGP 加密的大多数其他工具的基础。 它哪儿也不会去,依赖PGP就是依赖GPG。

【未完待续】


知识共享许可协议
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。