c14n和exc-c14n的核心区别在于命名空间处理:c14n包含所有作用域内的命名空间声明,而exc-c14n只包含当前元素或其子元素直接使用或声明的命名空间;2. 在处理空白字符、属性顺序、字符编码、实体引用、cdata节、注释和处理指令等方面,c14n和exc-c14n的处理规则完全一致;3. exc-c14n专为xml数字签名设计,确保被签名子树的规范化形式独立于外部上下文,具备可移植性和自包含性;4. 当对整个文档签名时c14n可行,但对局部元素签名时应使用exc-c14n以保证签名在不同上下文中仍有效;5. 因此,在xml数字签名中更倾向于使用exc-c14n,因其增强了签名的鲁棒性、减少对外部结构的依赖,并提升安全性和灵活性。

XML的Canonical XML(C14N)和Exclusive Canonical XML(Exc-C14N)之间的核心区别,在于它们在处理XML文档中的命名空间声明时,对于“作用域内”和“实际使用”的判断逻辑。简单来说,C14N会包含所有在作用域内的命名空间,而Exc-C14N则更“排他”,只包含那些被当前元素或其子元素直接使用或声明的命名空间,尤其是在处理XML文档的局部(子树)时,这一点变得至关重要。
我花了不少时间与XML签名打交道,深知Canonical XML(C14N)和Exclusive Canonical XML(Exc-C14N)之间的细微差别绝非小事,它直接影响着签名数据的有效性和安全性。
你可以把 Canonical XML (C14N) 理解为一种“全面公开”的版本。它的主要目标是消除XML文档中所有不影响逻辑意义的差异,确保两个逻辑上相同的文档能产生完全一致的字节流。这包括标准化属性顺序、空白字符、字符编码,以及非常重要的一点:命名空间声明。当C14N处理一个元素时,它会追溯整个祖先链,并包含所有“在作用域内”的命名空间声明,即使当前元素或其直接子元素并未明确使用它们。这保证了当你对整个文档进行规范化时,能得到一个始终如一的输出。然而,问题在于当你只想对文档的某个“部分”进行签名时。如果你提取一个子树,然后用C14N对其进行规范化,那些从其原始上下文继承的、未使用的命名空间仍然会被包含进来。这可能会导致问题,因为如果这个子树被移动到另一个XML文档中,而那些继承的命名空间在那里可能不在作用域内或可能发生冲突,那么规范化形式(以及签名)就会改变。
这正是 Exclusive Canonical XML (Exc-C14N) 介入的地方。它是一种更具针对性的方法,专为XML数字签名等场景设计,因为在这些场景中,你通常需要对特定的元素或子树进行签名。它的“排他性”意味着它会“排除”那些并非由当前元素或其子元素在被规范化的子树中直接使用或声明的继承命名空间。相反,它只包含那些在元素本身上“明确声明”的命名空间,或者那些在子树内部被元素或其属性/子元素“实际引用”的命名空间。这使得子树的规范化形式更加便携和自包含。你可以将这个已签名的子树复制、粘贴到另一个XML文档中,只要其内部结构和“自身”的命名空间声明保持一致,它的规范化形式(以及签名)就将保持有效,而无需考虑周围文档的命名空间上下文。
本质上,C14N追求的是文档级别的整体一致性,而Exc-C14N则追求子树级别的自给自足和可移植性。如果你要对整个文档进行签名,C14N通常是可行的。但如果你要签名的是像<signedinfo></signedinfo>元素或XML文档中的特定数据块,那么Exc-C14N几乎总是更正确、更安全的选择,以确保签名在被签名部分移动或重新上下文化时仍然有效。
为什么在XML数字签名中更倾向于使用Exclusive Canonical XML?
这确实是一个很常见的问题,它直接触及了实际应用的核心。在XML数字签名中,更倾向于使用Exc-C14N并非随意之举;它源于对健壮和可移植签名的基本设计要求。
当你对一个XML文档,或者更常见地,对其某个特定部分进行签名时,签名实际上是对该数据“规范化形式”的哈希值。如果规范化过程在不同上下文下对相同逻辑数据产生不同的结果,那么你的签名就会变得脆弱。
想象一下你有这样一个XML文档:
<root xmlns="http://example.com/ns1" xmlns:a="http://example.com/nsA"> <data a:attr="value"> <item xmlns:b="http://example.com/nsB">Some text</item> </data></root>
现在,假设你只想签名其中的<data></data>元素。
如果你使用 Canonical XML (C14N) 对<data></data>进行规范化,它的规范化形式会包含xmlns="http://example.com/ns1"和xmlns:a="http://example.com/nsA",因为它们在作用域内,从<root></root>继承而来,即使<data></data>本身只直接使用了a:attr。如果你随后将这个已签名的<data></data>元素嵌入到另一个XML文档中,例如,其中默认命名空间是http://example.com/ns2,或者xmlns:a未定义,那么对原始已签名<data></data>的C14N处理仍然会产生相同的结果(因为它基于其原始上下文)。但如果这个<data></data>元素被单独提取并签名,它的C14N形式仍然会携带那些继承的命名空间,使其自包含性较差。
而使用 Exclusive Canonical XML (Exc-C14N) 时,当你签名<data></data>元素,它将只包含在<data></data>上明确声明的命名空间,或者由<data></data>或其子元素使用的命名空间。在我们的例子中,它会包含xmlns:a="http://example.com/nsA"(因为a:attr被使用),但不会包含xmlns="http://example.com/ns1"(<root></root>的默认命名空间),除非<data></data>本身明确使用了默认命名空间。这使得已签名的<data></data>子树更具独立性。你可以复制它,粘贴到另一个XML文档中,只要内容及其“明确声明/使用”的命名空间保持不变,其Exc-C14N形式将是相同的,签名也将保持有效。
这种自包含的特性对于以下几个原因至关重要:
可移植性: 已签名的片段可以在文档之间移动而不会使签名失效。这对于分布式系统至关重要,因为XML片段可能在不同系统间传递。减少依赖: 签名的有效性较少依赖于周围的文档结构,更多地依赖于签名数据本身的完整性。清晰性和简洁性: 子树的规范化形式不会被潜在不相关的继承命名空间声明所混淆。
因此,本质上,Exc-C14N之所以受到青睐,是因为它生成的规范化形式对于周围XML上下文的变化具有鲁棒性,使得XML数字签名在对文档任意部分进行签名时更加可靠和灵活。它将签名内容隔离,使其成为一个真正原子化、可验证的单元。
Canonical XML和Exclusive Canonical XML在处理空白字符和属性顺序上有区别吗?
这是一个很好的澄清点,因为人们常常会混淆规范化的所有方面。答案非常直接:不,它们在处理空白字符和属性顺序方面没有区别。
Canonical XML (C14N) 和 Exclusive Canonical XML (Exc-C14N) 都建立在一套共同的规则之上,用于规范化XML文档的“物理”表示。它们的核心目的是消除那些不影响XML逻辑意义但可能改变其字节流的变体。
以下是两种规范化算法都一致执行的操作:
空白字符规范化:它们将所有换行符转换为#xA(LF)。它们删除元素内容中可忽略的空白字符(例如,元素之间的缩进)。文本节点内或xml:space="preserve"元素内的空白字符会被保留。属性顺序:元素内的属性按照命名空间URI然后是本地名称进行词法排序。这确保了a="1" b="2"和b="2" a="1"产生相同的规范化形式。命名空间声明(核心区别之外):它们确保命名空间声明被正确放置和添加前缀。它们在其各自的作用域内删除冗余的命名空间声明(例如,如果xmlns:foo="bar"在一个元素上声明,然后在子元素上以相同的URI重新声明,根据特定的规范化规则,子元素的声明可能会被删除,如果它是冗余的)。字符编码:输出始终是UTF-8。实体引用:所有实体引用(例如,&、<、自定义实体)都替换为其字符等效项。CDATA节:CDATA节被替换为其字符内容。注释和处理指令:默认情况下,注释和处理指令会从规范化形式中移除。存在一些特定变体(例如,“带注释”
以上就是XML的Canonical XML和Exclusive Canonical XML有什么区别?的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1430035.html
微信扫一扫
支付宝扫一扫