Cloudflare 自研工具 CryptoLabe 利用 AI 自动扫描代码库发现加密实现、梳理依赖关系,指导 2029 年完成全量后量子密码迁移。
来源:Cloudflare Blog
随着全球实验室竞相构建具有密码学相关性的量子计算机,我们在 Cloudflare 也在朝着 2029 年全面实现后量子就绪的目标截止日期全力冲刺。虽然我们已经将许多产品迁移到了后量子加密,但为了在整个平台上实现完整的后量子就绪状态,我们仍有大量工作要做——尤其是后量子认证方面。
我们采取的是一种"最大化"立场("一切都要 PQ!"),因为作为全球的基础设施提供商,我们希望给客户一个定心丸:使用 Cloudflare 就意味着他们的流量已经具备了对量子敌手的抗量子破解能力。
但在这样一个规模庞大的组织中,如何完成如此大规模的迁移?毕竟,密码学是几乎所有世界数字系统的基础层,包括为我们的平台提供动力的软件服务和网络协议。
为了推动我们的 PQ 迁移,我们设定了三个关键目标。
第一,我们希望帮助产品和工程团队了解密码学的使用方式以及如何对其进行升级。这既要涵盖后量子加密的升级,也要涵盖后量子认证的升级。我们的许多产品已经通过 TLS 1.3 升级到了后量子加密,但我们仍需覆盖 TLS 连接的"长尾"部分,以及其他公开密钥加密的所有使用场景。同时,我们的后量子认证部署仍处于早期阶段。
第二,我们希望提供迁移进度指标。这些指标可能包括每个代码仓库和每个产品的经典密码学与后量子密码学使用情况的统计。
第三,我们希望尽早发现前置依赖项。如果我们的产品或平台依赖的协议尚无 PQ 迁移计划(因为系统的 PQ 变体尚未被考虑,或者 PQ 标准不存在或缺乏共识,或者软件库或其他关键生态系统组件尚无 PQ 支持),那么我们现在就需要知道。这样我们才能与相关利益方、标准机构和生态系统合作,推动他们的 PQ 迁移计划,从而使我们能够按自己的 2029 PQ 迁移时间表完成目标。
这篇文章讲述的是我们如何推进这项工作。我们将解释我们如何借助 AI 来帮助解决一些问题,以及我们如何开发了一个名为 CryptoLabe 的内部工具。CryptoLabe 的名字来源于航海家的星盘(astrolabe),这是一种由葡萄牙航海家改进的导航仪器。正如星盘帮助水手确定所在位置并规划航线一样,CryptoLabe 帮助我们在代码中发现密码学、理解其使用方式,并规划后量子迁移的路径。
CryptoLabe 是高度针对我们的内部系统(我们的代码仓库、工单系统和内部文档流程)而定制的,并且随着我们持续开发仍在不断演进,因此我们不会将其提供给客户。不过,我们愿意分享我们的经验教训,以便其他组织在推进自己的 PQ 迁移之旅时能够在此基础上构建。
为大多数 Cloudflare 产品提供动力的软件位于我们单一集中的源代码管理平台中。这意味着,我们只需浏览代码库就能找到平台上大部分密码学的使用。
虽然代码库的集中化对我们来说是一个显著的优势,但我们仍然需要应对这一问题规模带来的三个挑战。首先,我们的代码分布在多个代码仓库中。其次,密码学在代码中很少会直接声明自己。相反,它隐藏在以下地方:
第三,密码学发现不仅仅是模式匹配。用 Grep 搜索某些算法名称(例如"RSA"或"X25519")会过度计数,因为它会找到未使用代码中的密码学。Grep 也会遗漏默认值以及依赖项和配置中的间接使用,从而导致计数不足。最重要的是,它无法告诉你密码学是如何被使用的。一个经典的 ECDSA 签名可能是 JWT、IPsec、TLS 或 SSH 的一部分,而每一种都有完全不同的迁移路径。许多用法还取决于连接的对方:TLS 服务器可能同时支持后量子密钥交换和经典密钥交换;它选择使用哪一种取决于客户端。
事实证明,AI 在执行超越 Grep 的工作方面相当擅长。模型可以搜索代码库、在文件间追踪证据,并返回结构化分析结果。它还可以通过从其他来源(如我们的内部文档和工单系统)提取信息来丰富发现内容。事实上,AI 甚至可以解释密码学的使用方式以及应如何更新。我们一直在将这个想法付诸实践,开发 CryptoLabe。
如前所述,我们的前两个目标是:(1)发现并理解我们代码库中密码学的使用情况,以及(2)获取我们 PQ 迁移状态的指标。为实现这些目标,我们目前实现的 CryptoLabe 以两个阶段执行扫描,如下图所示。

第一个"发现"(discovery)阶段从映射代码仓库开始,然后通过源代码、配置、清单文件、锁文件、脚本、测试和文档搜索密码学。扫描除了查找其他内容外,还会查找密钥协商、签名、非对称加密、公钥基础设施(PKI)、令牌、凭证、硬件安全模块集成等的密码学使用情况。这个发现阶段生成一组"原始观察"(raw observations)。
每个原始观察都会触发第二阶段的一次运行。这个"分析"(analysis)阶段首先将观察结果与源代码进行重新核对,然后调查加密操作在运行时的使用方式、仓库扮演的角色,以及它依赖于哪些内部或外部各方。在必要时,它可以检查其他仓库中的相关代码以完成分析。最后,它对自己的结论进行一遍检查,搜索可能缺失或冲突的证据,例如配置覆盖、仅用于测试的代码,或关于运行时行为的错误假设。
接下来,模型为发现结果分配一个分类。如果有证据不足以分配分类,模型会分配"需要更多证据"(More evidence needed)、"外部依赖"(External dependency)或"未知"(Unknown),而不是胡乱猜测。
以下是 CryptoLabe 目前使用的分类列表,包含了一些包罗万象的分类器,随着我们推进迁移工作,这些分类器可能会进一步细化。(举个例子,我们可以通过将"encryption"分类器拆分为密钥协商和 HPKE 来细化分类器——你懂的。)
密钥协商(Key agreement)
这是一个包罗万象的分类,用于发现椭圆曲线 Diffie-Hellman 密钥交换(ECDHE)(如 X25519、P-256、P-384)、RSA 密钥协商或公开密钥加密的其他使用(如 HPKE)。这些会被运行 Shor 算法的量子计算机攻破,因此面临"现在收集,以后解密"(harvest-now-decrypt-later)攻击的风险。
签名(Signatures)
这是一个包罗万象的分类,用于发现在任何地方使用的 RSA 签名或椭圆曲线(ECDSA)签名,例如证书、TLS 握手、其他协议握手。这些签名会被 Shor 算法攻破。
经典 JWT(Classical JWT)
我们发现了大量 RS256 或 ES256 JWT 令牌,因此为它们创建了一个特殊分类。这些是使用经典 RSA 和 ECDSA 签名的 JWT;RFC 9964 定义了使用 ML-DSA 的后量子替代方案。
PQ-ready 混合密钥交换(PQ-ready hybrid key exchange)
发现 TLS 1.3 中的混合后量子密钥交换,即 X25519MLKEM768。这是我们代码库中最普遍的后量子加密使用形式。
其他后量子(Other post-quantum)
发现 TLS 1.3 中 X25519MLKEM768 以外的后量子密码学的其他使用,如 ML-DSA。
最后,它生成一份服务于两类受众的报告:(1)需要了解迁移对其产品意味着什么的产品经理,以及(2)需要足够细节来执行迁移的工程师。
这是我们某份报告的(裁剪后的)视图:

虽然我们一直在与相关工程师一起迭代审查发现结果与源代码的对照情况,但我们尚无一个真值数据集(ground-truth dataset)来可复现地比较我们为 CryptoLabe 尝试过的不同版本的提示词。
我们基于 Cloudflare 的开发者平台构建了 CryptoLabe。以下是架构:
CryptoLabe 运行在两个 Cloudflare Workers 上。有一个扫描 Worker 运行扫描,还有一个资产清单 Worker 提供仪表板、暴露 API,并将所有内容存储在 D1 数据库中。两者通过 Service Bindings 通信。当有人从仪表板发起扫描请求时,资产清单 Worker 将请求传递给扫描 Worker。
我们需要一种方式让扫描从开始到结束都保持活跃且可控,而不需构建自己的作业编排系统。我们通过 Agents SDK 实现了这一点。每个代码仓库都有自己基于 Durable Object(DO)构建的持久化协调器。协调器前有一个有界队列,限制同时运行的扫描数量。当轮到某个扫描时,协调器会跟踪其进度并处理取消、重试和恢复。
协调器本身不做分析工作。它将工作交给 Cloudflare Workflows,以便它们可以持久化进度并自动重试失败的步骤。协调器将每个代码仓库推进四个阶段:
discovery Workflow(第一个扫描阶段,产生原始观察结果)
deep analysis Workflow(第二阶段,对每个原始观察结果运行分析)
merge Workflow(为给定代码仓库构建发现列表,包括合并重复或相似的发现)
publish workflow(将结果交回资产清单 Worker)
前两个 Workflow 需要模型能够访问代码仓库的代码。我们希望这种访问是隔离的,以免损坏代码库。这就是为什么 CryptoLabe 在每次扫描开始时将代码仓库下载一次(精确到某个提交),然后将该快照存储在 R2 中。然后每个 Workflow 将快照恢复到全新的、短生命周期 Cloudflare Sandbox(一个隔离容器)中。然后模型通过一组只读工具与该只读代码快照一起工作,即使代码库在扫描仍在运行时发生变化。
如果我们想扫描我们(很多!)代码仓库,需要同时关注成本和容量。
在成本方面,模型循环通过 AI Gateway 发送请求,由 Workers AI 上托管的性价比高的开源模型处理。将模型放在 AI Gateway 后面还可以轻松切换到更好或更便宜的模型。
一旦同时扫描许多代码仓库,容量就成了问题。模型请求的突发开始触发 HTTP 429(速率限制)响应,而且各个扫描独立重试只会使突发更加严重。我们通过一个单一的全局 Durable Object 来解决这个问题,它为所有扫描中的每个模型请求(包括重试)设置节奏。当任何扫描遇到速率限制时,冷却是共享的,所有扫描一起退让,因此并发扫描共享可用容量而不是相互竞争。
现在让我们进入第三个目标:尽早暴露前置条件和困难案例。
关于 PQ 迁移的生态系统准备已经有很多讨论,我们现在也要再讨论一下。众所周知,PQ 迁移不能在真空中进行。要使迁移成功,后量子密码学必须在相关软件库(如 BoringSSL)和参与生态系统的各方(如客户端、浏览器、源站、云代理、证书颁发机构等)中得到支持。标准也是生态系统支持的重要指标,尽管仍处于"草稿"状态的标准不一定意味着不能进行部署。例如,我们在 2022 年就在 TLS 1.3 中部署了 X25519MLKEM768,当时它在互联网工程任务组(IETF)还是"草稿",直到 2026 年才最终成为 RFC 10024。
无论如何,我们的观点是,要将系统升级到 PQ 密码学,我们需要了解其依赖关系和生态系统支持水平。
这就是为什么 CryptoLabe 使用"前置条件"的概念来突出那些无法由单个产品团队单独立即修复的发现。
前置条件可能很简单,比如"我们目前无法迁移到后量子 JWT"。我们称之为简单,是因为后量子 JWT 已经有了标准(RFC 9964)。然而,如果我们的软件库尚不支持验证后量子 JWT,或者我们使用的令牌颁发者尚未颁发后量子 JWT,我们就无法在公司范围内要求每个产品团队开始将他们的 JWT 量子化。在这个核心前置条件解决之前,此迁移是受阻的。CryptoLabe 允许我们将可能有相同前置条件的发现分组在一起,这也帮助我们决定如何优先解决这些前置条件。
例如,下面的快照显示了 CryptoLabe 中六个以后量子 SAML 作为前置条件的发现。(SAML 是一种单点登录(SSO)协议。)

另一方面,有些密码学用法可能甚至缺乏基本的生态系统支持。我们称之为"困难案例"。为了找到它们,我们编写了一个单独的 prompt,忽略"普通"密码学用法(例如内部系统之间的普通 TLS),转而寻找自定义密码学协议、在大小受限字段中使用的密钥或签名、嵌入硬件的密码学、专用密码学构造(如盲签名)、没有 PQ 标准的协议,以及依赖尚不支持 PQ 密码学的外部各方。
这个 prompt 比 CryptoLabe 使用的 prompt 更短更简单,因为它唯一的工作就是找到困难案例。在我们的定性审查中,我们发现当它一次性对所有代码仓库运行,同时结合来自我们内部工单和文档系统的上下文时,效果更好。
以下是我们发现的一个"困难案例"示例:携带在 HTTP 头部中的证书。后量子证书和签名比其经典对应物更大,因此如果头部(或中间件,或处理头部的应用程序)假定证书具有特定大小,更改签名算法可能会破坏系统。我们的下一步是确定这段代码是否会在长期内继续使用。如果会,我们需要测量相关的大小限制,并决定如何容纳更大的证书。
一个重要的教训是,没有单一扫描能找到所有东西。我们按代码仓库逐个扫描在发现常见密码学用法方面很有效。同时,这种针对性扫描对"困难案例"效果更好,因为它忽略了众所周知的密码学,并有更多关于每个产品及其依赖项的上下文。
底线是:不同的方法会发现不同的东西,每项发现仍然需要由了解系统实际工作方式的工程师来检查。
在过去几个月里,我们一直在研究为 CryptoLabe 编写 prompt 的最佳方法。我们还没有用于比较一个 prompt 与另一个 prompt 性能的 ground-truth 数据集,也不确信我们的代码库中所有密码学用法都有 100% 的覆盖率。相反,我们通过运行扫描、与维护代码仓库的工程师一起审查发现、在这些审查中调查遗漏并修改 prompt 来迭代。尽管如此,我们决定发布精选的 prompt,以便其他团队可以学习并适应我们的方法。这些 prompt 是起点,而不是独立版本的 CryptoLabe,其结果质量将取决于可用的模型、工具、上下文和工程审查。
在 Cloudflare,我们对自己的 PQ 迁移采取了最大化的方法,因为我们目标是成为客户和整个互联网后量子密码学的提供者。但大多数组织不需要从在每个产品的每个代码仓库中找到每一种密码学用法开始。事实上,大多数组织不应该这样做,因为在现阶段这是对宝贵资源的浪费。
在扫描单个代码仓库之前,你可以尽可能批量保护流量。如果你的网站通过 Cloudflare 运营,我们今天已经使用后量子加密保护你的传输数据;请使用我们新的 PQ 可视化功能查看。我们的 SASE 平台 Cloudflare One 为私有网络流量提供后量子加密。后量子加密不收取额外费用,也不需要你升级企业网络上的每个源服务器或私有应用程序。这为你提供了一个补偿控制措施,同时你继续努力发现和理解自己系统内部的密码学使用情况。
详尽的密码学清单并非行动的前提条件。相反,组织应首先识别那些被攻陷后影响最大的系统,发现它们对密码学的使用,然后按优先级将这些密码学方案迁移到 PQ。以下是一种启动方式:
为一个重要系统选择一个代码库。从处理敏感数据或长期数据、验证用户或软件身份、或暴露在公共互联网上的系统入手。
对该代码库运行密码学发现。我们希望对 CryptoLabe 的描述能对此工作有所帮助!
验证结果。请拥有该系统的团队验证密码学发现的结果,并确认该密码学发现是否长期需要,以及是否需要升级为 PQ。重要的是要记住,如果存在其他补偿性控制措施,可能不需要立即升级到 PQ。
优先排序行动。确定哪些升级现在可以做,哪些被阻塞了。记录需要库供应商、厂商、标准组或组织内其他部门帮助的共同前提条件。对发现进行优先级排序,制定计划首先处理影响最大的系统和前提条件。
这样你就得到了 PQ 迁移计划的开端,无需对组织内每一次密码学操作都绘制完整地图。CryptoLabe 仍在不断演进,但在我们规划迁移时,它的扫描和结果已经给我们带来了很多启发。我们希望这些共享经验对你们继续推进自己的 PQ 迁移有所帮助。
致谢:Cloudflare 内部许多人在 CryptoLabe 的开发和反馈中做出了贡献,包括 Davide Marquês、Peter Wu、Phil Schmieder、JP Aumasson、Andrew Galloni、Christopher Patton、Luke Valenta、Mari Galicer、Vânia Gonçalves,以及审查了该工具生成的报告的 Client、Tunnel 和 Gateway 团队。