Summary

  • RFC 2440 定义了许多 OpenPGP 数据包标签,却没有提供永久增加标签的常规流程,因为新旧功能之间的相互作用可能降低整个协议的安全性。
  • 头部有可用编号,不代表获得扩展许可。60 至 63 保留给私有或实验用途;新的取值请求应交由 IESG 安全领域主管或合适的 IETF 工作组审议。
  • 在签名子包中,未知类型通常会被忽略;关键位允许签名者宁可让验证出错,也不愿让新功能的意义被静默丢弃。识别不等于实现,未哈希元数据也不是决定性证据。
  • 后续版本建立了明确的注册表和审查规则。取值已分配、解析成功或签名有效,仍不能证明组合安全或实际部署。

空位并没有替人做决定

设想一位开发者在 OpenPGP 数据包里发现一个尚未使用的标签。两个新客户端都能写入并读回它,测试通过了。字节确实放得下。但旧版验证器会怎么处理?协商时能否把这项功能降级?另一个数据包会不会改变它的含义?新语义即使被忽略,签名是否仍会在数学上验证成功?本地往返测试都回答不了这些问题。

RFC 2440 在 1998 年 11 月的 IESG 注记中写下了这层顾虑。规范定义了很多标签,却没有增加新标签的常规机制。新格式头部可以表示到 63 的标签值,但文档警告,新旧功能之间细微甚至明显的交互,都可能显著削弱整体安全性。新的取值请求——例如新的加密算法——应提交 IESG 安全领域主管,或转交适当的工作组。60 至 63 仅用于私有或实验用途。编号空间存在,并不意味着安全扩展流程也自然存在。

OpenPGP 不是一袋互不相关的算法。数据包会组合成密钥、签名和加密消息。新功能可能改变旧软件解析数据包序列的方式,也可能改变新软件解释旧字段的方式,或改变接收方对签名覆盖范围的理解。语法允许某个标签,不代表其交互已经被研究。RFC 2440 把编码能力与协议许可分开处理。

签名让边界变得清晰

签名子包在更小的尺度上呈现了同样的张力。忽略未知子包有利于前向兼容:旧软件仍可处理附带新元数据的签名。因此 RFC 2440 建议忽略无法识别的子包类型。但静默忽略也可能抹去签名者依赖的功能。

子包类型的第 7 位提供了一个选择。如果未知子包被标记为关键,验证者就应将签名视为错误。签名者可以选择显式失败,而不是让验证者丢弃其含义后仍然接受。这并非万能保证:验证者必须理解该规则;即使能够识别某个子包,也可能尚未实现其语义。规范明确区分了识别和实现。

即便某个数据被识别并附在有效签名旁边,也不一定拥有签名的权威性。子包可以位于已哈希或未哈希部分。RFC 2440 警告,未哈希部分的信息并非决定性,因为它不属于签名本身。读取者看见了它、验证器解析了它,都不代表它受到密码学覆盖。存在、解析、识别、实现和覆盖是不同状态。

从谨慎到注册表

2007 年取代 RFC 2440 的 RFC 4880 建立了明确的 IANA 注册表,并要求新增数据包类型须经 IETF 共识,因为它们属于重要功能。它还指出,与修改检测相关的扩展可能带来降级和交叉降级风险。治理流程因此更清晰,但互操作、实现和安全分析并没有因此变成同一个勾选框。

2024 年发布的 RFC 9580 取代了 RFC 4880,并保留了不同层级的分配程序。部分 OpenPGP 注册表使用 Specification Required;数据包类型及部分版本、身份编号空间则要求 RFC Required。指定专家还需审查新取值能否保留预期安全属性,并与现有实现互操作。这是对早期流程缺口的制度性回应,却不能证明获准的每项扩展在所有部署环境中都安全。

这些文档并未断言所有扩展都有害,也没有证明所有实现者遵循同一种做法。它们揭示的是更有限、也更有用的历史事实:在密码协议中,新增一种含义可能改变已有路径的行为。空闲整数只是格式中的一个地址,不能证明兼容性、密码学覆盖、用户理解或运维安全。

来源