摘要
- RFC 3741 让抽出的 XML 片段不再自动携带大部分祖先命名空间声明,主要只序列化元素名或属性名实际可见使用的前缀。
- 这并不代表片段的语义也与上下文无关:未继承的
xml:属性以及只出现在属性值里的前缀,都可能让目标应用在重新封装后作出不同解释。
外层消息不应改写内层载荷的签名
设想一个协议在大型 XML 消息里签署一个小元素。网关剥掉外层包装,另一个服务再把同一元素放进新信封。传统的包含式 Canonical XML 会把某些祖先命名空间声明和 xml: 属性纳入规范化字节,即使该片段本身没有用到它们。这样一来,只改变外壳,就可能改变摘要输入,让未改动的片段验签失败。
RFC 3741 于 2004 年 3 月发布,针对的正是这类摩擦。它为 XPath 节点集定义了一种独占 XML 规范化方式:大部分继承命名空间不会被带入;只有元素名或属性名实际使用的前缀才会在输出中声明。调用方还可以通过 InclusiveNamespaces PrefixList,点名某些虽不可见使用、却仍须按包含式规则处理的前缀。目标是让已签名子文档能够脱离原有封装再加入新封装,而不让无关包装层左右其规范字节。
这是一项边界选择,不是“脱离上下文也含义不变”的承诺。RFC 3741 自己就明列了限制。这与 RFC 3075 讨论签名覆盖哪些变换结果、RFC 3076 讨论解析后节点集如何变成规范字节不同;RFC 3741 专门处理被选中的子集移动时应留下哪些上下文。
“可见使用”有用,但范围很窄
算法以 XML 名称判定可见使用。元素名或属性名用了 n1 前缀,就要为对应名称保留 n1 的绑定;如果祖先声明了一个片段名称没有用到的前缀,它就可以被省略。协议外壳可能声明了许多外层消息用的命名空间,其中一些与被抽出的载荷无关。独占规范化能够去掉这些噪声,让同一载荷在不同外壳下得到相同规范字节。
但应用语义可能依赖节点集里看不见的内容。例如,属性值里的 XPath 表达式可能引用前缀;应用也可能把 xsi:type="xsd:decimal" 这样的字符串当作 QName 来处理,尽管 XPath 数据模型只把属性值看成字符串。如果没有可见使用、也没有加入前缀列表,xsd 绑定可能被省略。接收端在新封装中的解释就可能不同。
RFC 提供三种处理方式:把前缀的使用改成结构上可见;确保每个解释环境都存在相同绑定;或将该前缀列入 InclusiveNamespaces PrefixList。这三种方式都要求应用设计者事先知道哪些值带有命名空间语义。前缀列表不是自动侦测隐藏 QName 的机制。
未进入签名字节的上下文仍可能支配解释
独占规范化也不会把祖先上的 xml:lang、xml:space 或 xml:base 复制到成为孤立节点的子集中。这些属性可能影响语言选择、空白处理和相对 URI 的解析。RFC 要求应用把必要值明确放到子集内部,或者保证每个解释环境都提供等效值。
它在目标上下文部分的例子更直接:片段被移到带有不同默认命名空间的新祖先下面,规范化八位组可以保持不变;然而,接收应用可能把无前缀元素归入另一个命名空间,从而视为不同类型的对象。签名仍然通过,因为选中的字节没有变;应用理解却可能改变,因为目的地的上下文变了。
RFC 3741 没有规定如何抽取、插入或修补命名空间声明,也没有决定接收方是否有权执行该操作。协议必须说明相关上下文如何随片段传递,消费者如何解释结果。密码学完整性只是链条中的一环。
签名边界缩小,集成责任扩大
独占规范化用显式管理语义依赖,换掉了对外层包装的偶然依赖。转发已签名片段时,审查者不能只问“验签是否成功”,还要问:目标位置上的前缀绑定、xml: 属性、QName 值和相对引用是否仍然意味着同一件事。若这些依赖没有写进协议,签名稳定就容易被误当成语义稳定。
这是标准描述的风险边界,不是某次攻击或实现故障的证据。RFC 3741 属于 Informational 文档;它证明算法的目的和限制,不证明某个实现的部署普及率,也不指向某个服务处理失当。它留下的教训更窄:从签名字节中省略上下文可以提升可移动性,但只有应用知道被省略的哪些信息仍决定解释。
来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
