摘要

  • RFC 9995 把哈希输出本身放进 COSE payload,强制在受保护头中声明 payload_hash_alg,并允许受保护地提示原像类型与位置。
  • 验证者无需持有原像,也能验证签名或 MAC;成功只覆盖信封、密钥与应用上下文所定义的密码学范围,不证明原件可用、安全、新鲜、语义正确或可被用于某项动作。
  • 依赖方仍须完成整条执行链:确认签名身份与用途、受限取回、保留精确字节、重算并比对、解析和评估、授权具体使用,最后观察实际影响。

设想发布委员会面对两项事实。第一,COSE_Sign1 验证通过。第二,系统找不到它声称对应的 SBOM。若界面只有一个“verified”,第一项事实会悄悄吞掉第二项事实。

RFC 9995 于 2026 年 7 月作为 IETF Standards Track RFC 发布。它定义 COSE Hash Envelope,让发送者保护一个大对象的摘要,而不必把大对象一同送入签名服务或验证通道。远程签名可以更便宜,受限链路可以少传数据,已经拥有原件的接收方也不必重复接收。

这种效率不是把原件压进了信封,而是明确不交付原件。标准的价值正在于边界清楚:摘要可以先被认证,原件的存在、相等、意义和使用许可必须由后续步骤分别建立。

必须分清三个对象

第一是原像,即真正被哈希的逐字节对象:SBOM、固件、审计包或其他内容。第二是摘要,即哈希算法的短输出;RFC 9995 把它作为 COSE payload。第三,普通 COSE 规则允许连这份短摘要也采用 detached payload 方式,在验签时由外部提供。

所以“payload 不在信封里”可能描述两个截然不同的缺席:大原像本来就不随 Hash Envelope 传输;小摘要还可能进一步从序列化结构中分离。日志若只写“外部 payload 已提供”,就无法回答系统究竟拿到了 32 字节摘要,还是拿到了几百兆的目标对象。

RFC 9052 定义 COSE 的基础结构。以 COSE_Sign1 为例,签名结构涵盖受保护头、应用选择的外部认证数据,以及参与 Sig_structure 的完整 payload;不受保护头不在同一保护范围内。Hash Envelope 里的 payload 是摘要,因此被覆盖的是摘要值,而不是未出现的原像。

这允许离线设备先完成一项真实的验证。但它不能在原像缺席时做逐字节比对,也不能从对象中获得任何业务效用。合格的状态机至少需要“信封有效”和“原像匹配”两种独立结果。

258、259、260 是坐标,不是原件

payload_hash_alg 的标签号是 258。它必须存在于受保护头,并且不得出现在不受保护头。它声明哪种哈希算法产生了 payload 中的摘要;攻击者不能在不破坏保护的情况下换掉这项坐标。

preimage_content_type 的标签号是 259,可选但一旦出现就受保护。它说明原像字节的媒体类型或 CoAP Content-Format。它不是普通 COSE content_type 标签 3:后者会描述当前 payload,也就是摘要。RFC 9995 禁止标签 3,正是为了避免把“摘要的类型”和“原像的类型”混成一个字段。

payload_location 的标签号是 260,同样可选且受保护。它可以是字符串或 URI,为取得原像提供线索。受保护意味着这条线索不能被无声篡改;不意味着地址一定在线、仍属原主人、值得信任、可以携带凭据访问,或此刻仍返回相同内容。

IANA COSE 注册表 为这些标签提供稳定编号和规范引用。RFC 8126 解释注册策略如何维持公共协调。登记完成并不证明某个库实现正确,也不证明某个信封合规,更不替运营者决定是否接受。

RFC 8610 给 CDDL 结构语法。语法可以让解析器发现字段缺失或位置错误,却不能证明数据来自谁、对象在哪里或用途是否正当。RFC 7252 提供 CoAP Content-Format 名空间;格式编号能帮助选解析器,却不替解析器验证内容,更不替业务政策判断内容。

数学成立以后,身份问题才真正出现

签名验证成功可以证明:在所选算法、输入和密钥假设成立时,受保护头与摘要没有在签名后被更改。MAC 则在共享秘密的参与方之间提供相应保护。这不是空洞结果,但范围有限。

密钥不会自己说明“我是谁”。RFC 9052 明确把两项责任留给应用:把验证密钥绑定到正确身份,并确认该身份有权进行当前动作。测试密钥可以签出数学有效的结果;只获准出具归档收据的密钥也可以。它们都不因此成为生产发布批准者。

外部认证数据可以绑定租户、版本或事务等上下文,前提是应用配置定义了确切字节,且双方使用同一构造。空白或泛化的外部上下文不会因签名通过而自动获得环境含义。

RFC 9421 提供相邻对照:HTTP Message Signatures 选择 HTTP 组件并依赖应用配置解释权限。Hash Envelope 不是 HTTP 请求签名,位置字段也不是请求授权。两者共同提醒运营者:签名只在被精确定义的组件与用途内成立。

因此审计状态要拆开:结构正确;密码学运算通过;密钥绑定到身份;身份仍有效;身份获准为此用途签署;外部上下文匹配。不能用一个绿色图标抹平其中任何一步。

签名位置不是自动取回指令

验证者也许已经持有原像,也许完全离线,也许只能通过受控代理取得材料。RFC 9995 允许依据位置查找,却没有要求自动解引用。没有原像的验证者能够验证信封,不能做哈希比对,也不能使用对象本身。

危险来自高权限验证服务:它若无条件访问签名 URI,签名者便间接获得让控制平面发起网络请求的能力。地址可能指向内网,重定向可能跨越域名,凭据可能被转发,压缩内容可能在解压后膨胀,旧域名也可能已经换了主人。即便签名者原本可信,密钥也可能被盗;“位置字段完整”不等于“目的地安全”。

RFC 9110 区分 HTTP 资源、表示、内容编码、位置与重定向。取回策略必须明确允许的 scheme 和 origin、重定向上限、DNS/TLS 结果、凭据规则、时限、字节上限、解压预算与网络隔离,并记录最终来源及发生过的转换。

RFC 6920 区分基于哈希的命名与寻找对象的机制。这一分离允许镜像更替:不同位置可以提供候选字节,哈希负责在取得以后证明是否匹配。位置帮助发现,摘要裁决身份;二者不应互相冒充。

必须先约定究竟哈希哪些字节

拿到候选对象后,验证者用标签 258 指定的算法重算,并与 COSE payload 比较。文件名、版本号、仓库 key 或媒体类型都不能替代这次运算。

问题在于,一个抽象资源可能具有不同字节表示。RFC 9530 区分 HTTP Content-Digest 与 Repr-Digest,内容编码会让同一信息对应不同摘要;这些 Digest 字段自身也不提供认证、授权或隐私。

应用配置必须提前写清:被哈希的是存储中的压缩文件、解码后的内容、规范化序列化,还是其他精确定义的字节流。先解析 JSON 或 CBOR 再重新序列化,字段顺序、空格、数字形式都可能改变。自动转换换行、透明解压,也会制造一个“看起来相同、摘要不同”的对象。

稳健顺序是:保存收到的原始字节;只做配置明确允许的转换;对指定字节重算;比较结果;把输入、算法和结果一并留证。

匹配成功只把摘要声明传递给这些确切字节,安全性受哈希与信封算法共同约束。它没有证明对象新鲜、无害、完整或适合业务动作。

相等以后才轮到解析与判断

一份字节完全匹配的 SBOM 仍可能无法解析;能够解析仍可能不合 schema;schema 合格仍可能属于另一版构建;版本正确仍可能遗漏依赖;内容完整仍可能暴露政策禁止的组件。

标签 259 给出解析坐标,不是语义判决。RFC 9995 也没有统一的新鲜度规则:旧字节可以永远与旧摘要相等,旧签名也可能长期通过。依赖方必须自行绑定时间、版本、受众、撤销状态与拟议用途。

标准覆盖 COSE_Sign、COSE_Sign1、COSE_Mac 和 COSE_Mac0,不覆盖 COSE_Encrypt 与 COSE_Encrypt0。它不提供保密,也不决定未来复合方案是在加密前还是加密后哈希。执行固件、公开文件或支付款项更不是该信封授予的权力。

算法标识同样不能替运营者迁移。RFC 9053 定义 COSE 算法和参数检查。RFC 9995 要求签名/MAC 与哈希组合的安全强度至少不削弱 payload 哈希。RFC 7696 则说明算法敏捷性是一套主动过程:生产端能发新算法,消费端在过渡期同时支持,政策设定旧算法拒绝日期,长期存档获得明确处理。注册表里仍有编号,不代表本地还应接受。

执行过的链条才是证据

Heng Lu 的运行代码优先原则要求查看真实执行轨迹,而非配置口号。证据包括:原像精确字节、生产时哈希、信封字节、算法与密钥、身份和用途判断、位置策略、取回路径、重算值、比对、解析器、语义政策、动作授权和最终效果。

他的最小初始规范与本地未来决策观点恰好解释 RFC 9995 的分工。公共标签、保护位置与结构语法提供最低协调;下载权限、格式白名单、新鲜度、签名者角色、算法退役、留存和回滚由本地责任人决定。地方自主必须配套可验证结果。

现实层次则阻止界面用“验证完成”折叠不同事实:信封能解析;签名通过;身份正确;原像取得;字节匹配;语义合格;动作获准;结果符合预期。任一层成功,都不能借给下一层权力。

本文资料证明的是协议与公开思想边界,不是采用率、性能、故障率或某个产品实现。SBOM 场景依据标准自身的 SPDX 示例构造,只用于解释,不代表现实厂商部署。