摘要

  • RFC 9688 并没有给所有 SHA3 相关算法套用同一种 ASN.1 参数规则:摘要、ECDSA、HMAC 与 HKDF 要求参数缺席,RSA PKCS#1 v1.5-with-SHA3 要求参数包含 NULL,KMAC 则由 customization 是否存在决定参数状态。
  • OID 被识别、解析器返回成功、签名通过或界面显示“SHA3”都只是局部回执,不能证明原始字节被保留、正确分支被执行、密钥与策略适用,更不能替代应用结果。

设想一份对象进入归档系统时,签名能够验证。系统把它解析成内部结构,再用统一规则重新编码。运维界面前后都显示“RSA with SHA3-256”,但新编码把 RSA 签名算法标识里的 NULL 删除了。RFC 9688 对这一分支的要求不是“NULL 可有可无”,而是必须存在。人眼看到的名称没有变化,协议对象却已经不是原来的对象。

这不是对某个产品事故的描述,而是一个分析场景。它揭示的事实很简单:OID 负责协调算法名称,却不单独承载完整的 AlgorithmIdentifier、所在 CMS 字段、参数存在性、嵌套标识、输入字节、密钥选择、实际执行路径与本地授权。

同一家族,三种参数状态

RFC 9688 把 SHA3-224、SHA3-256、SHA3-384 与 SHA3-512 放进 CMS 的多个位置。作为摘要算法时,它们可以出现在 SignedData.digestAlgorithms、SignerInfo.digestAlgorithm、DigestedData.digestAlgorithm 与 AuthenticatedData.digestAlgorithm。这些标识符的参数必须缺席,不能用 ASN.1 NULL 代替缺席。

ECDSA-with-SHA3 的签名算法参数同样必须缺席。HMAC-with-SHA3 也如此。四个 HKDF-with-SHA3 标识符仍然要求缺席。因此,一个沿用旧习惯、习惯给每个算法标识补上 NULL 的通用编码器,会在 OID 看起来完全正确时生成不符合本规范的对象。

RSA PKCS#1 v1.5-with-SHA3 恰好相反。rsaEncryption 以及四个 RSA-with-SHA3 签名标识符的参数字段必须包含 NULL。若“清理器”把 NULL 当成没有意义的装饰统一删除,它会破坏这一分支。

KMAC 不允许任何“一刀切”。KMAC128-KDF 与 KMAC256-KDF 没有 customization 标签 S 时,参数必须缺席;只要发送方提供 S,参数就必须存在,并以 OCTET STRING 精确保留。缺席与“存在一个零长度字符串”不是可以由界面随意合并的状态。它们是不同编码,也可能代表不同输入结构。

所以真正的最小公共层不是“支持 SHA3”四个字,而是每个字段位置对应的精确规则。本地策略可以决定接受哪些算法,却不能先改写公共语法,再把改写后的对象称作收到的原件。

KMAC 的 OID 无法重建派生过程

RFC 9688 把 KMAC 写成 KMAC128(K, X, L, S) 或 KMAC256(K, X, L, S)。K 是派生密钥,常见来源是 KEM 解封装输出;X 是上下文,在 RFC 9629 的使用中包含 CMSORIforKEMOtherInfo 的 DER 编码;L 是输出位长;S 是可选 customization 标签。

如果日志只记录 id-kmac128,它至少丢失了三个影响结果的非密钥输入。即使 OID 与参数字节都在,仍需要精确的 X 与 L。发送方和接收方若构造出不同上下文,同一个 OID 不会自动让派生结果一致。

KDF2 与 KDF3 还把摘要 AlgorithmIdentifier 嵌套在自身参数中。如果内部选用 SHA3,该内部标识符也必须遵守 Section 2 的参数缺席规则。只检查外层 KDF OID 的验证器只能给出残缺的合规结论。

资产清单因此不应只有“SHA3:是”。可用的能力声明应至少写明 CMS 角色、算法 OID、参数形态、嵌套规则、可接受的 BER/DER 表达、密钥接口与已验证输出。两个绿色勾选如果没有这组坐标,可能代表两条完全不同的执行路径。

先保存收到的字节,再追求可读性

解码器的职责是把编码对象变成可用结构,但如果它丢弃原始字节,再把内部结构重新序列化为一个“更标准”的副本,它也会销毁证据。某个库可能同时接受缺席与 NULL,把两者映射成同一个空值,随后按自己的默认习惯输出其中一种。应用只看见一个状态,网络上原本却有两个。

事件调查和迁移至少需要四份回执:收到的 CMS 原始字节哈希;字段路径与精确 OID;参数状态及参数字节哈希;由明确版本的密码实现和策略生成的操作结果。如果发生转换,还要另记转换后字节哈希。经过规范化的副本不能冒充收到的原件。

密码学成功也有边界。RSA 或 ECDSA 签名验证通过,只证明选定字节、签名、公钥与算法之间的一种关系。它不自动证明证书路径在相关时间有效、签署者有权批准内容、对象足够新鲜、内容类型符合业务语义,或下游应用已经提交动作。

可核验的链条应当逐层保留:

  1. 记录内容字节与 CMS 内容类型;
  2. 记录摘要、签名、MAC 或 KDF 的字段角色;
  3. 记录精确 OID;
  4. 记录参数是缺席、NULL 还是某段 customization;
  5. 记录嵌套算法标识;
  6. 哈希收到的完整编码;
  7. 标明解析器版本以及是否做过规范化;
  8. 标明密码实现、密钥引用与实际操作;
  9. 记录验签、MAC 比较或 KDF 结果;
  10. 单独记录证书、密钥用途与本地策略判断;
  11. 单独记录应用结果。

任何一盏绿灯都不应跨层升级。

注册表是坐标,不是部署报告

RFC 9688 促成了四个 HKDF-with-SHA3 标识符与一个 ASN.1 模块标识的 IANA 分配。这种唯一坐标让独立实现能够谈论同一对象,价值明确。但它不是安装量统计,也不证明某个库能够解析、正确编码、调用正确提供者、保护正确密钥或与另一实现互通。

名录最擅长协调名称;运行代码提供的是另一类事实:捕获字节、测试向量、差分解析结果和应用回执。把两层分开,才不会让符号上的存在冒充现实中的执行。

来源