来源: https://blog.cloudflare.com/bootstrap-mtc/
世界各国正竞相建造首台量子计算机,以解决即使是规模最大的传统超级计算机也无法解决的实际问题。量子计算范式虽然前景广阔,但也威胁着互联网安全,因为它会破解我们赖以生存的大部分加密技术。
为了缓解这一威胁,Cloudflare 正在帮助互联网向后量子 (PQ) 加密技术迁移。目前, Cloudflare 边缘网络约 50%的流量受到保护,免受最紧迫的威胁:攻击者可以拦截并存储加密流量,然后在未来借助量子计算机对其进行解密。这种威胁被称为“先收获后解密”的 威胁。
然而,这只是我们需要应对的众多威胁之一。量子计算机还可以用来破解服务器的TLS证书,使攻击者能够冒充服务器,欺骗毫无戒心的客户端。好消息是,我们已经有了可用于量子安全认证的PQ算法。坏消息是,在TLS中采用这些算法将需要对互联网上最复杂、最关键的安全系统之一——Web公钥基础设施(WebPKI)——进行重大改造。
核心问题在于这些新算法的庞大体积:ML-DSA-44 是 NIST 标准化的最高效的 PQ 算法之一,其签名长度为 2420 字节,而目前最流行的非 PQ 签名算法 ECDSA-P256 的签名长度仅为 64 字节;ML-DSA-44 的公钥长度为 1312 字节,而 ECDSA-P256 的公钥长度也仅为 64 字节。这大约是 ECDSA-P256 的 20 倍。更糟糕的是,平均每次 TLS 握手都包含大量的公钥和签名,每次握手都会增加数十 KB 的开销。这足以对 TLS 的性能产生显著影响。
这使得目前推广即插即用的PQ证书变得非常困难:在Q日(即具有密码学意义的量子计算机问世之日)之前,它们并不能带来任何安全优势,反而会降低性能。我们可以坐等Q日到来,但这无异于玩火。迁移总是比预期花费的时间更长,而等待会危及我们珍视的互联网安全和隐私。
显然,我们必须找到一种方法,使后量子证书的成本足够低,以便所有人都能默认部署,而不仅仅是那些负担得起的人。在本文中,我们将向您介绍我们与行业合作伙伴共同向 IETF 提交的计划,该计划旨在重新设计 WebPKI,从而实现向后量子身份验证的平滑过渡,且不会影响性能(甚至可能提升性能!)。我们将概述一项名为Merkle 树证书 (MTC)的具体提案,其目标是将 TLS 握手中的公钥和签名数量减少到所需的最低限度。
但光说不练是不够的。我们从经验中得知 ,任何互联网变革都必须尽早且频繁地进行测试。今天,我们宣布计划与 Chrome 安全团队合作,以实验性质部署 MTC(移动终端)。 在本文中,我们将介绍此次实验的范围、我们希望从中获得的经验,以及我们将如何确保实验安全进行。
如今的 WebPKI 是一个老旧的系统,打了很多补丁。
为什么TLS握手需要这么多公钥和签名?
让我们从密码学基础知识开始。当浏览器连接到网站时,它会请求服务器进行身份验证 ,以确保正在与真正的服务器通信,而不是冒充者。这通常通过一种称为数字签名方案(例如 ECDSA 或 ML-DSA)的加密原语来实现。在 TLS 中,服务器使用其私钥对客户端和服务器之间交换的消息进行签名,客户端则使用服务器的 公钥 验证签名。这样,服务器就向客户端确认了双方进行的通信是同一回事,因为只有服务器才能生成有效的签名。
如果客户端已经知道服务器的公钥,那么只需要一次签名 即可验证服务器身份。然而,在实践中,这并非一个可行的方案。如今的互联网由大约十亿台TLS服务器组成,因此为每个客户端都配备所有服务器的公钥是不现实的。此外,随着新服务器的上线和现有服务器密钥的轮换,公钥集合也会随之变化,因此我们需要某种方式将这些变更推送给客户端。
扩展性问题是所有公钥基础设施设计的核心。
信任具有传递性
服务器不必事先要求客户端知道其公钥,而是在TLS握手过程中直接发送公钥。但客户端如何确定该公钥确实属于服务器呢?这就需要证书来验证了 。
证书将公钥与服务器的身份绑定——通常是其 DNS 名称,例如cloudflareresearch.com 。证书由证书颁发机构 (CA) 签名,客户端知道 CA 的公钥。除了验证服务器的握手签名外,客户端还会验证此证书的签名。这建立了一条信任链:客户端接受证书即表示其信任 CA 已验证该公钥确实属于具有该身份的服务器。
客户端通常配置为信任多个证书颁发机构 (CA),并且必须为每个 CA 配置一个公钥。不过,由于 CA 的数量只有几百个而不是数十亿个,情况就简单多了。此外,创建新证书无需更新客户端。
这些效率的提升是以相对较低的成本实现的:对于那些在家计算的人来说,这意味着每次 TLS 握手需要**+1 个** 签名和**+1 个** 公钥,总共需要2 个签名和 1 个公钥 。
然而,故事并未就此结束。随着 WebPKI 的发展,这些信任链也随之变长。如今,一条信任链通常包含两个或多个证书,而不仅仅是一个。这是因为证书颁发机构 (CA) 有时需要 像服务器一样轮换密钥。但在启用新密钥之前,CA 必须将相应的公钥分发给客户端。这需要时间,因为这需要数十亿客户端更新其信任存储。为了弥补这一时间差,CA 有时会使用旧密钥为新密钥颁发证书,并将该证书附加到信任链的末尾。
这样我们就有了1 个 签名和1 个 公钥,总共有3 个签名和 2 个公钥 。但我们还有一段路要走。
信任,但要核实
证书颁发机构 (CA) 的主要职责是验证服务器是否拥有其申请证书的域的控制权。多年来,这一过程已从高度依赖人工干预的 CA 特定流程演变为标准化的、高度自动化的流程,用于颁发网络上的大多数证书。(但并非所有 CA 都完全支持自动化。)这一演变过程中也出现了一些安全事件,在这些事件中,证书被错误地颁发 给了服务器以外的第三方,使得该第三方能够冒充服务器,欺骗任何信任该 CA 的客户端。
自动化固然有所帮助,但攻击仍然可能发生,错误几乎不可避免。今年早些时候,Cloudflare 加密的 1.1.1.1 解析器的多个证书在未经我们参与或授权的情况下被颁发。这显然是意外造成的,但仍然使 1.1.1.1 的用户面临风险。(这些错误颁发的证书已被撤销。)
确保错误颁发的证书能够被检测到是证书透明度 (CT) 生态系统的职责。其基本理念是,每个证书颁发机构 (CA) 颁发的证书都会被添加到公共日志 中。服务器可以审核这些日志,查找以其名义颁发的证书。如果发现任何未经其自身请求而颁发的证书,服务器运营商可以证明该证书的颁发确实发生过,而公钥基础设施 (PKI) 生态系统可以采取措施,阻止客户端信任该证书。
包括 Firefox 和 Chrome 及其衍生版本在内的主流浏览器都要求证书必须先被记录在日志中才能被信任。例如,Chrome、Safari 和 Firefox 只会接受服务器证书,前提是该证书至少出现在浏览器配置为信任的两个日志中。这条策略说起来容易,做起来难:
- 维护证书跟踪日志历来成本相当高昂。日志在其生命周期内会记录数十亿份证书:当发生事件,甚至只是在高负载情况下,日志也需要一段时间才能生成新的条目供审计人员使用。
- 客户无法自行审核日志,因为这会将他们的浏览历史记录(即他们想要连接的服务器)暴露给日志操作员。
解决这两个问题的方案是在证书中包含来自 CT 日志的签名。该签名会在收到证书日志记录请求后立即生成,并证明日志会在 24 小时内将该证书添加到日志中。
根据浏览器策略,证书透明度会在 TLS 握手过程中增加2 个 签名,每个日志对应一个签名。因此,在公共网络上,典型的握手过程总共需要5 个签名和 2 个公钥。
未来的 WebPKI
WebPKI是一个鲜活的、不断更新的、高度分布式的系统。多年来,我们不得不多次对其进行修补以维持其正常运行,但总的来说,它一直很好地满足了我们的需求——直到现在。
以前,每当我们需要更新 WebPKI 中的某些内容时,我们都会添加一个新的签名。这种策略之所以有效,是因为传统的加密技术成本很低。但是,对于即将到来的更大规模的 PQ 签名而言,每次 TLS 握手平均需要5 个签名和 2 个公钥, 这实在难以应对。
好消息是,通过巧妙地调整我们已有的资源,我们可以大幅减少所需的签名数量。
默克尔树证书速成课程
Merkle 树证书 (MTC)是我们正在实施并计划以实验方式部署的下一代 WebPKI 提案。其主要特性如下:
- 客户端验证默克尔树证书所需的所有信息都可以通过带外方式分发。如果客户端足够新,TLS 握手只需要1 个签名、1 个公钥和 1 个默克尔树包含证明 。即使使用后量子算法,这仍然非常精简。
- MTC 规范通过让每个 CA 运行自己的日志,准确记录他们颁发的证书,从而将证书透明度作为 PKI 的一项重要功能。
让我们深入了解一下。下面是我们内部测试生成的 MTC(消息传递代码)。它会在 TLS 握手过程中从服务器传输到客户端:
-----BEGIN CERTIFICATE-----
MIICSzCCAUGgAwIBAgICAhMwDAYKKwYBBAGC2ksvADAcMRowGAYKKwYBBAGC2ksv
AQwKNDQzNjMuNDguMzAeFw0yNTEwMjExNTMzMjZaFw0yNTEwMjgxNTMzMjZaMCEx
HzAdBgNVBAMTFmNsb3VkZmxhcmVyZXNlYXJjaC5jb20wWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAARw7eGWh7Qi7/vcqc2cXO8enqsbbdcRdHt2yDyhX5Q3RZnYgONc
JE8oRrW/hGDY/OuCWsROM5DHszZRDJJtv4gno2wwajAOBgNVHQ8BAf8EBAMCB4Aw
EwYDVR0lBAwwCgYIKwYBBQUHAwEwQwYDVR0RBDwwOoIWY2xvdWRmbGFyZXJlc2Vh
cmNoLmNvbYIgc3RhdGljLWN0LmNsb3VkZmxhcmVyZXNlYXJjaC5jb20wDAYKKwYB
BAGC2ksvAAOB9QAAAAAAAAACAAAAAAAAAAJYAOBEvgOlvWq38p45d0wWTPgG5eFV
wJMhxnmDPN1b5leJwHWzTOx1igtToMocBwwakt3HfKIjXYMO5CNDOK9DIKhmRDSV
h+or8A8WUrvqZ2ceiTZPkNQFVYlG8be2aITTVzGuK8N5MYaFnSTtzyWkXP2P9nYU
Vd1nLt/WjCUNUkjI4/75fOalMFKltcc6iaXB9ktble9wuJH8YQ9tFt456aBZSSs0
cXwqFtrHr973AZQQxGLR9QCHveii9N87NXknDvzMQ+dgWt/fBujTfuuzv3slQw80
mibA021dDCi8h1hYFQAA
-----END CERTIFICATE-----
看起来像是一个普通的PEM编码证书。我们来解码并查看一下参数:
看起来像是一个普通的PEM编码证书。我们来解码并查看一下参数:
$ openssl x509 -in merkle-tree-cert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 531 (0x213)
Signature Algorithm: 1.3.6.1.4.1.44363.47.0
Issuer: 1.3.6.1.4.1.44363.47.1=44363.48.3
Validity
Not Before: Oct 21 15:33:26 2025 GMT
Not After : Oct 28 15:33:26 2025 GMT
Subject: CN=cloudflareresearch.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:70:ed:e1:96:87:b4:22:ef:fb:dc:a9:cd:9c:5c:
ef:1e:9e:ab:1b:6d:d7:11:74:7b:76:c8:3c:a1:5f:
94:37:45:99:d8:80:e3:5c:24:4f:28:46:b5:bf:84:
60:d8:fc:eb:82:5a:c4:4e:33:90:c7:b3:36:51:0c:
92:6d:bf:88:27
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:cloudflareresearch.com, DNS:static-ct.cloudflareresearch.com
Signature Algorithm: 1.3.6.1.4.1.44363.47.0
Signature Value:
00:00:00:00:00:00:02:00:00:00:00:00:00:00:02:58:00:e0:
44:be:03:a5:bd:6a:b7:f2:9e:39:77:4c:16:4c:f8:06:e5:e1:
55:c0:93:21:c6:79:83:3c:dd:5b:e6:57:89:c0:75:b3:4c:ec:
75:8a:0b:53:a0:ca:1c:07:0c:1a:92:dd:c7:7c:a2:23:5d:83:
0e:e4:23:43:38:af:43:20:a8:66:44:34:95:87:ea:2b:f0:0f:
16:52:bb:ea:67:67:1e:89:36:4f:90:d4:05:55:89:46:f1:b7:
b6:68:84:d3:57:31:ae:2b:c3:79:31:86:85:9d:24:ed:cf:25:
a4:5c:fd:8f:f6:76:14:55:dd:67:2e:df:d6:8c:25:0d:52:48:
c8:e3:fe:f9:7c:e6:a5:30:52:a5:b5:c7:3a:89:a5:c1:f6:4b:
5b:95:ef:70:b8:91:fc:61:0f:6d:16:de:39:e9:a0:59:49:2b:
34:71:7c:2a:16:da:c7:af:de:f7:01:94:10:c4:62:d1:f5:00:
87:bd:e8:a2:f4:df:3b:35:79:27:0e:fc:cc:43:e7:60:5a:df:
df:06:e8:d3:7e:eb:b3:bf:7b:25:43:0f:34:9a:26:c0:d3:6d:
5d:0c:28:bc:87:58:58:15:00:00
虽然有些参数看起来可能很熟悉,但另一些则可能不太常见。熟悉的方面,主题和公钥正如我们所预期的那样:DNS 名称是 [DNS_NAME] cloudflareresearch.com ,公钥是 [公钥],对应的签名算法是熟悉的 ECDSA-P256。当然,这个算法不是 PQ——将来我们会用 ML-DSA-44 代替。
不同寻常的是,OpenSSL 似乎无法识别颁发者的签名算法,而只是打印出原始的 OID 和签名字节。这背后有一个合理的解释:MTC 中根本没有签名!那么,我们究竟看到了什么?
省略签名的诀窍在于,默克尔树认证机构 (MTCA) 会批量而非逐个生成无签名证书。证书上没有签名,取而代之的是一份包含**证明 ,表明 该证书包含在 MTCA 签名的一批证书之中。
为了理解包含证明的工作原理,我们来看一个稍微简化的 MTC 规范版本。为了颁发一批证书,MTCA 会将未签名的证书整理成一个名为默克尔树的 数据结构,其结构如下所示:
树的每个叶子节点对应一个证书,每个内部节点的值等于其子节点的哈希值。为了对证书批次进行签名,MTCA 使用其私钥对树的根节点进行签名。树的结构保证了批次中的每个证书都由 MTCA 签名:如果我们试图修改其中任何一个证书的位,树的根节点的值就会改变,从而导致签名失败。
证书的包含性证明由从证书到树头的路径上每个兄弟节点的哈希值组成:

给定一个已验证的树头,该哈希序列足以证明证书包含在树中。这意味着,为了验证 MTC,客户端还需要从 MTCA 获取已签名的树头。
这就是MTC高效运作的关键:
- 已签名的树头文件可以通过带外方式分发给客户端,并进行离线验证。每个经过验证的树头文件随后可用于验证相应批次中的任何证书,从而无需为每个服务器证书获取签名。
- 在 TLS 握手过程中,客户端会告知服务器它拥有哪些树头文件。如果服务器拥有一个包含在这些树头文件中的无签名证书,那么它就可以使用该证书进行身份验证。每次握手需要1 个签名、1 个公钥和 1 个包含证明 ,所有这些都是针对被验证的服务器的。
以上是简化版。真正的 MTC 还有一些更高级的功能。首先,它不会为每个批次创建一个单独的 Merkle 树,而是构建一个大型的单一树,以提高透明度。随着这棵树的增长,系统会定期选择(子)树头并将其发送给浏览器,我们称之为**“地标”** 。通常情况下,浏览器可以获取最新的地标,服务器可以等待批次证书的颁发,但我们需要一个备选方案:MTC 也支持可以立即颁发且无需验证地标的证书,但这些证书体积较大。服务器会同时配置这两种类型的 Merkle 树证书,以便在常见情况下快速响应,在特殊情况下缓慢响应,但至少能够正常工作。
实验性部署
自默克尔树证书(MTC)的早期设计出现以来,我们就一直渴望对其进行试验。秉承 IETF 的“运行代码”原则,通常需要实际实现协议才能解决设计中的问题。同时,我们也不能拿用户的安全冒险。在本节中,我们将介绍如何在不 改变任何信任关系的前提下,对默克尔树证书设计的各个方面进行试验。
让我们先从我们希望了解的内容开始。我们有很多问题,这些问题的答案可以帮助验证该方法,或者发现需要重新设计协议的缺陷——事实上,Maximilian Pohl和Mia Celeste对早期 MTC 草案的实现正是如此。我们想知道:
什么会出问题? 协议僵化(实现中的缺陷导致协议难以修改)是部署协议变更时始终存在的问题。特别是对于 TLS 而言,尽管它内置了灵活性,但我们一次又一次地发现,如果这种灵活性没有得到经常利用,就会出现实现缺陷,中间设备在遇到无法识别的内容时就会崩溃。TLS 1.3 的部署正是由于这个原因,比我们预期的时间长了好几年。而最近,TLS 中 PQ 密钥交换的推出导致客户端 Hello 被拆分到多个 TCP 数据包中,许多中间设备对此还无法应对。
性能影响如何? 事实上,我们预计 MTC 能够减小 握手包的大小,即使与目前的非 PQ 证书相比也是如此。它们还能降低 CPU 成本:ML-DSA 签名验证的速度与 ECDSA 相当,而且需要验证的签名数量将大大减少。因此,我们预计延迟会降低 。我们希望看到性能方面有可衡量的提升。
有多少客户端会保持证书更新? 要充分发挥多级证书 (MTC) 的性能优势,客户端和服务器之间必须保持大致同步。我们预计 MTC 的有效期较短,大约一周左右。这意味着,如果客户端的最新证书日期超过一周,服务器就必须回退到有效期更长的证书。了解这种回退发生的频率将有助于我们调整协议参数,从而降低回退的概率。
为了解答这些问题,我们正在TLS协议栈和证书颁发基础设施中实现MTC支持。Chrome也在自己的TLS协议栈中实现MTC支持,并将搭建基础设施向用户分发相关标志。
正如我们以往的实验一样,我们计划为一部分流量足以获取有效数据的免费用户启用 MTC(移动终端)。Chrome 将负责控制实验性的推广:他们可以逐步增加推广规模,边推广边进行测量,并在发现问题时及时回滚。
最后还有一个问题:谁将运营 Merkle Tree CA?
从现有 WebPKI 引导信任
建立一个合格的证书颁发机构(CA)绝非易事:它需要数年时间才能获得主流浏览器的信任。因此,Cloudflare 不会成为本次实验的“真正”CA,Chrome 也不会直接信任我们。
为了在合理的时间范围内取得进展,同时又不牺牲尽职调查,我们计划“模拟”MTCA 的作用。我们将运行一个 MTCA(基于我们的StaticCT 日志,在Workers上运行),但对于我们颁发的每个 MTC,我们还会发布一个来自受信任 CA 的、与之匹配的现有证书。我们称之为引导证书 。当 Chrome 的基础架构从我们的 MTCA 日志中拉取更新时,它们也会拉取这些引导证书,并检查它们是否匹配。只有当它们匹配时,才会将相应的标记推送给 Chrome 客户端。换句话说,Cloudflare 实际上只是将一个现有证书(由受信任的 CA 执行域名验证)“重新编码”为 MTC,而 Chrome 则利用证书透明性来确保我们的诚信。
结论
目前我们近 50% 的流量已经受到后量子加密的保护,这意味着我们距离完全后量子安全的互联网已经迈出了一半的步伐。然而,后量子证书——我们旅程的第二部分——却是迄今为止最艰难的。在量子日之前,简单的升级会带来明显的性能影响,且无法带来任何安全收益。这意味着,要让后量子证书成为默认启用选项并非易事。但我们现在就像在玩火:迁移总是比预期花费更长的时间。如果我们想要维护一个无处不在的私密和安全互联网,我们就需要一个性能足够强大的后量子解决方案,以便今天 就能默认启用。
Merkle 树证书 (MTC) 通过将签名和公钥的数量减少到最低限度,同时保持 WebPKI 的基本属性,解决了这个问题。我们计划在明年初之前向部分免费账户推出 MTC。这不会影响任何未参与 Chrome 实验的访问者。对于参与实验的用户,由于使用了引导证书,安全性不会受到影响。
