Cloudflare Workers 开放后量子密码算法:如何试用 ML-KEM 与 ML-DSA

2026-10-01 12 预计阅读时间: 1 分钟
来源: blog.cloudflare.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

Cloudflare Workers 正在加入对 ML-KEM 和 ML-DSA 的可选支持。这两类算法面向后量子安全场景:ML-KEM 用于建立共享密钥,ML-DSA 用于数字签名。由于功能采用 opt-in 方式开放,现有 Worker 不会因为运行时升级而被迫改变密码学行为,团队可以先在测试环境验证兼容性和性能。

两种算法解决的不是同一个问题

ML-KEM 是密钥封装机制(Key Encapsulation Mechanism,KEM)。它的核心用途是让通信双方建立共享秘密,再用这个秘密派生对称密钥。它并不是一个可以直接替换 AES 的“文件加密算法”,也不应被当作普通公钥加密接口使用。

ML-DSA 则是数字签名算法,适合完成两件事:

  • 私钥持有者对消息或摘要签名;
  • 验证方使用公钥确认数据来源和完整性。

在实际系统中,两者通常处于不同链路。例如,服务间握手可以评估 ML-KEM,构建产物、配置清单或 Webhook 消息则可以评估 ML-DSA。不要因为它们都带有“后量子”标签,就把两个 API 混成同一种用途。

还需要注意,“后量子抗性”表示算法被设计为抵抗已知量子攻击模型,并不意味着实现天然没有风险。随机数质量、密钥生命周期、侧信道、日志泄漏和错误的协议组合,仍然可能让一个算法正确的系统变得不安全。

为什么 opt-in 很重要

密码算法进入边缘运行时,不只是多了两个函数。密钥尺寸、签名长度、计算开销以及上下游协议支持,都可能与现有算法不同。

采用 opt-in 模式至少带来三个好处:

  1. 避免静默改变现有应用。 老 Worker 可以继续保持原有行为。
  2. 允许逐环境验证。 团队可以先在开发或预发布环境打开支持,再观察延迟、CPU 时间和错误率。
  3. 方便做协议协商。 当客户端、边缘节点和源站尚未全部支持新算法时,可以保留经典算法或混合模式作为兼容路径。

这里最容易踩的坑,是只在 Worker 中启用算法,却没有检查调用方和密钥管理系统。边缘代码能够生成 ML-DSA 密钥,不代表现有 HSM、证书系统、数据库字段或消息格式就能正确保存和使用它。

在 Worker 中做一个最小能力探测

下面是一个可以放进现有 Workers 项目的探测端点。它不会把密钥返回给客户端,只检查当前运行时能否识别并生成相应类型的密钥。

假设与边界: 示例假设运行时通过 Web Crypto 风格的 crypto.subtle 暴露算法。算法名称、参数以及具体 opt-in 配置可能随 Workers 当前实现而变化;运行前应按照当前控制台或项目配置启用该能力,并以运行时文档列出的标识符为准。即使名称不匹配,端点也会返回结构化错误,不会让 Worker 崩溃。

将以下内容保存为 src/index.js:

async function probe(label, algorithm, usages) {
  const startedAt = performance.now();

  try {
    const keyPair = await crypto.subtle.generateKey(
      algorithm,
      false,
      usages
    );

    return {
      algorithm: label,
      supported: true,
      elapsedMs: Number((performance.now() - startedAt).toFixed(2)),
      keyTypes: {
        publicKey: keyPair.publicKey?.type ?? null,
        privateKey: keyPair.privateKey?.type ?? null
      }
    };
  } catch (error) {
    return {
      algorithm: label,
      supported: false,
      elapsedMs: Number((performance.now() - startedAt).toFixed(2)),
      error: error instanceof Error ? error.message : String(error)
    };
  }
}

export default {
  async fetch(request) {
    const url = new URL(request.url);

    if (url.pathname !== "/crypto-capabilities") {
      return new Response("Not found", { status: 404 });
    }

    const results = await Promise.all([
      probe("ML-KEM-768", { name: "ML-KEM-768" }, []),
      probe("ML-DSA-65", { name: "ML-DSA-65" }, ["sign", "verify"])
    ]);

    return Response.json({
      runtime: "Cloudflare Workers",
      checkedAt: new Date().toISOString(),
      results
    });
  }
};

在已有 Workers 项目中可以这样启动本地开发服务器:

npx wrangler dev

然后从另一个终端调用:

curl -s http://localhost:8787/crypto-capabilities

部署到已启用相应能力的测试环境后,再用实际域名检查:

curl -s https://YOUR-WORKER.example.workers.dev/crypto-capabilities

这个端点适合做一次性验证,但不建议原样公开到生产环境。生产部署前可以增加管理员鉴权,或者在完成兼容性测试后直接删除探测路由。

不要从“能生成密钥”直接跳到生产签名

能力探测通过,只能说明运行时接受对应 API。下一步应验证完整生命周期:

  • 密钥在哪里生成、保存和轮换;
  • 私钥是否允许导出,以及是否真的需要导出;
  • 公钥和签名如何编码、传输与版本化;
  • 消费方是否支持相同的算法参数;
  • 签名、密文和公钥尺寸是否超过数据库或消息队列限制;
  • 失败时是拒绝请求、回退到经典算法,还是进入混合模式;
  • 日志、追踪和异常对象中是否可能出现敏感材料。

如果系统需要长期保密,还应优先评估“先记录、后解密”风险:攻击者可能今天保存流量,等未来具备更强计算能力时再尝试解密。相反,如果只是给短生命周期的内部消息签名,迁移节奏和威胁模型可能完全不同。

建议的落地顺序

一个稳妥的采用路径是:先做能力探测,再做互操作测试,随后进行小流量试运行,最后才讨论默认启用。测试时至少记录调用次数、P50/P95 延迟、CPU 时间、失败类型和数据体积变化。

同时保留算法版本字段,不要把 ML-KEM 或 ML-DSA 硬编码成永远不变的系统默认值。密码迁移的关键能力不是“选中一个新算法”,而是让协议、密钥和数据格式在下一次升级时仍然可以平滑演进。


相关推荐