摘要

  • RFC 9708 规定 HSS/LMS 公钥和签名如何进入 X.509、PKIX 与 CMS。LM-OTS 私钥只能签名一次,因此签名者必须准确、持久地记录哪些叶节点已经用过。
  • 某一份签名验证成功,并不能证明签名者的全局状态没有分叉。写盘失败、虚拟机快照回滚或克隆,都可能把已经消耗的叶节点再次标成可用。
  • 核心控制是先不可逆地推进状态,再让签名离开安全边界;同时保证只有一个有效写入者,并能把每份输出和唯一的状态预留凭据对应起来。

凌晨的签名服务没有报错。它生成的对象能被公钥验证,证书链也照常工作。真正的问题发生在更早的恢复动作里:系统管理员启动了一份旧快照。快照不知道在拍摄之后已有若干签名交付给外部,于是它再次拿出了同一批一次性密钥。

这正是 RFC 9708 所揭示的运行边界。该标准轨文档于 2025 年 1 月发布,更新了分层签名系统 HSS 和 Leighton–Micali 签名方案 LMS 在证书、PKIX 与密码消息语法中的表示方式,取代 RFC 8708,处理既有勘误并加入新的参数集合。这些改进解决互操作问题,却不会消除 HSS/LMS 的有状态本质。

底层规则来自 RFC 8554。私钥状态包含下一个一次性签名索引。签名操作不仅产出签名,还产出后继私钥状态;树中可用叶节点耗尽后,就不存在下一个状态。如果同一秘密状态被使用两次,规范不再提供密码学安全保证,攻击者甚至可能获得伪造其他消息的条件。

因此,要保管的资产不是一串静止的秘密,而是“秘密材料加上已消耗历史”。其中任何一半失真,公钥表面上的稳定都会掩盖真实风险。

验证一份对象,不等于验证整段历史

LM-OTS 为每把私钥限定一次签名。LMS 把多把一次性密钥放入 Merkle 树,HSS 又可以把树分层组合,由此获得数量可观但仍然有限的签名预算。验证者看到签名里的叶节点位置与认证路径,可以确认该对象和公钥之间的数学关系。

它看不到另一台机器、另一个时间点是否用过同一位置。一次验证是局部事实;状态唯一性是跨越所有副本、写入者、备份和故障转移路径的全局事实。两者之间至少存在以下凭据阶梯:

凭据 能够得出的有限结论
公钥被策略接受 依赖方认可这把 HSS/LMS 公钥
算法标识被解析 编码和参数集合可被理解
签名验证通过 当前对象符合验证算法
叶节点索引可见 当前签名声明了一个树位置
状态已经预留 某个写入者分配了该位置
后继状态已持久化 非易失存储不再提供该位置
签名已经交付 结果离开了模块或服务边界
全局对账完成 没有第二份输出占用同一位置
业务结果出现 下游基于签名内容采取了行动

“签名通过”不能替代“全局对账完成”。RFC 9708 明确要求实现追踪已经使用的叶节点,并警告追踪完整性丢失会导致一次性密钥复用。它列举的危险并不神秘:持久化写入可能失败,虚拟机可能被拍快照或克隆。常规基础设施动作足以破坏密码学所依赖的时间方向。

签名交付之前,状态必须先落地

如果服务先计算并返回签名,随后才保存递增后的索引,断电可以落在两者之间。外部调用者已经拿到签名,恢复后的服务却会再次选择同一叶节点。即使写接口返回成功,数据仍可能停留在易失缓存;只有在崩溃后仍能证明前进,才算真正持久。

NIST SP 800-208 把状态管理视为有状态哈希签名最难保证的部分。其合规配置要求模块先增加叶节点标识,并在非易失存储中持久保存,再导出签名或接受下一项签名请求。安全顺序可以写成一条不可交换的链:预留下一个位置;把“不得再用”写入持久介质;在受控状态下完成签名;连同预留凭据交付;对不确定结果进行核对,但绝不把该位置退回可用池。

如果系统在持久化之后、导出之前崩溃,一片叶节点可能被白白消耗。浪费降低容量,却没有破坏一次性承诺。反过来,为节约叶节点而允许重用,会把容量问题变成安全问题。有疑问时留下一个序号空洞,比留下两份共享一次性秘密的公开签名更安全。

这套逻辑与通常的无状态云服务相反。重试未必幂等;恢复备份未必恢复安全;复制镜像未必只是水平扩容。对活动中的 HSS/LMS 私钥而言,时间必须单向流动。

高可用可能复制签名权

两个持有相同私钥状态的活动实例,可以分别产生完全有效的签名,同时分配到重叠叶节点。共享数据库不能自动消除风险:如果任一节点能在事务持久化前导出签名,数据库锁只是晚到的记录。硬件模块也不是抽象保证:相同状态若被复制到两个模块而没有互斥分区,硬件只会让两个副本都更可靠地犯错。

可行方案包括:由一个权威模块串行消费;向不同签名者分配互不重叠的子树;利用单调硬件计数器阻止或揭示回滚;先隔离旧写入者,再让故障转移节点获得权限。关键是证明具体边界。“使用硬件”不是独占状态的凭据,“高可用”也不是单写入者的同义词。

NIST 配置比 IETF 的一般编码规则更严格:它限定获批参数集合,要求密钥与签名生成位于硬件密码模块内,并禁止导出秘密密钥。这是声称符合该配置的系统应满足的条件,不能反推所有 RFC 9708 实现都具备同样保护。标准发布证明规范存在;产品说明证明厂商作出过表述;只有运行凭据能证明某次恢复期间状态没有倒退。

证书和 CMS 能携带公钥,却携带不了签名者的记忆

RFC 9708 规定对象标识符以及 AlgorithmIdentifier 的参数必须缺省,HSS/LMS 公钥也不再额外包一层 ASN.1 结构。在 X.509 证书中,密钥用途必须与签名相符,而不能表示加密或密钥协商。其表示方式与 RFC 5280 的证书框架和 RFC 5912 的 ASN.1 模块相衔接。

在 RFC 5652 定义的 CMS 中,实际被签名的字节取决于是否存在签名属性。没有属性时直接签内容;存在属性时,内容先被摘要,签名覆盖 SignedAttributes 的 DER 编码,其中包含内容类型和消息摘要。由 RFC 4108 描述的固件封装等场景因此能沿用既有容器。

这些规则回答“哪些字节怎样验证”,没有回答“私钥状态是否只有一份”。证书能够在签发策略下把公钥与主体绑定,却不能列出旧快照中是否还有一份私钥状态。CMS 验证者能看到受保护属性,看不到签名设备内部丢失的一次磁盘刷新。使用范围越广,内部状态凭据越重要。

有限预算必须成为治理对象

叶节点数量由参数与树结构决定。机构需要预估签名速率、服务寿命、保留余量、替换公钥和分发新证书所需时间。异常消耗可能来自攻击、正常发布高峰或观测故障,但三种情况都会改变剩余预算。索引耗尽不能回绕;恢复旧索引也不是扩容,而是伪造账本。

IANA LMS 注册表 记录标准化类型码。RFC Editor 信息页、规范的纯文本与 XML 版本、IETF 文档历史和勘误记录共同构成公开的标准证据。它们都不会告诉读者某个生产签名者还剩多少叶节点,也不会替它证明灾备流程正确。

Heng Lu 的运行代码原则把问题落到可执行转移:输出越过边界前,状态是否已经不可逆地前进?最小初始规范提供共同互操作底线,却保留部署者对硬件、隔离和恢复的本地选择。现实层次的区分则要求我们不要把“已有标准”“对象验证成功”和“运行历史安全”压缩成一个绿色状态。

RFC 9708 并没有削弱 HSS/LMS 的价值。它揭示的是责任迁移:系统减少对某些可能受量子计算影响的数学假设的依赖,却把更重的责任交给状态存储、写入独占与恢复纪律。机器必须记得每一次消耗,而且必须能够证明自己不会忘记。

来源