XML Signature(也称作XMLDsig,XML-DSig,XML-Sig)是一个定义数字签名的XML语法的W3C推荐标准。从功能上或,XML Signature与PKCS#7有很多共同点,但是XML签名具有更好的可扩展性,并为签名XML文档做了调整。XML Signature在许多Web技术,如SOAP, SAML等中使用。
XML signature可以用来签名任何类型的数据(称作资源),最常见的是XML文档,但是任何可以通过URL访问的资源都可以被签名。如果XML签名用于对包含该签名的XML文档之外的资源签名,则称为detached signature如果XML签名用于对包含它的XML文档的某个部分进行签名,则称为enveloped signature;如果XML签名包含被签名的数据,则称为enveloping signature。
一个XML签名包含一个Signature元素,其名字空间为http://www.w3.org/2000/09/xmldsig#。基本结构如下所示:
<Signature>
<SignedInfo>
<SignatureMethod />
<CanonicalizationMethod />
<Reference>
<Transforms>
<DigestMethod>
<DigestValue>
</Reference>
<Reference />等
</SignedInfo>
<SignatureValue />
<KeyInfo />
<Object />
</Signature>
当验证一个XML签名时,需要遵守一个称作核心验证(Core Validation)的程序:
这一程序确定该资源是否是真的由宣称的当事人签名的。然而由于XML标准化和转换方法的可扩展性,验证方必须同时确认实际被签名或摘要的正式在原始数据中出现的内容,换句话说,确信签名或摘要所使用的算法没有改变被签名的数据的意思。
XML签名的产生要比通常的数字签名的产生复杂一点,这有由于一个给定的XML文档(在XML开发人员通用的说法是"XML信息集")可能包含合法的序列化的表达方式以外的内容。例如,在XML元素中的白空格从句法上说是没有意义的,因此<Elem >和<Elem>没有区别。
由于数字签名是由非对称密钥加密算法(通常是RSA加密演算法)对序列化的XML文档进行散列(通常是SHA1)的结果进行加密。一个字节的差别会导致数字签名的不同。
此外,如果XML文档是在计算机间传输,不同操作系统的換行符可能不同,从CR到LF再到CR LF等。 对XML文档进行摘要和验证的程序可能随后以不同的方式呈现XML。例如,在元素定义的属性定义间添加额外的空格,或是使用相对的(而不是绝对的)URL,或者改变XML命名空间定义的顺序。标准化的XML对于引用远端文档的XML数字签名尤其重要,远端服务器可能会随时间改变XML呈现的方式。
为了避免这些问题,并保证逻辑上相同的XML文档会产生相同的数字签名,在对XML文档进行签名(在对SignedInfo进行签名时,规范化是强制的)时使用了一种XML规范化的转换(Canonicalization,通常缩写为C14n)这些算法保证逻辑上相同的文档产生完全相同的序列化的表达方式。
缺省的规范化算法处理命名空间生命的方式带来了另一个问题;通常来说一个被签名的XML文档需要嵌入另一个文档;在这种情形下,原来的规范化算法产生的结果与单独的文档规范化的结果不同。由于这个原因,一个被称为Exclusive Canonicalization的规范化算法产生了,该算法在序列化一个元素的XML命名空间声明时独立于该元素所嵌入的XML文档。
与其他形式的数字签名,如Pretty Good Privacy和Cryptographic Message Syntax相比,XML Signature更加灵活,这是因为它操作的不是二进制数据,而是XML信息集,允许操作数据的子集,可以以不同形式将签名与被签名的信息结合,以及可以执行转换。另一个核心概念是标准化,也就是说仅对“精华”进行签名,而排除了无意义的区别,如白空格和换行符。
通常,批评都对准XML安全的体系结构[2],以及在签名和加密XML数据前对XML进行规范化的适宜性,这是因为XML规范化的复杂性,内在的处理需求,以及性能不高的特性[3] [4] [5].争论在于执行XML标准化会导致额外的等待时间,这对事务的,性能敏感的SOA应用来说简直难以克服。
这些问题正在XML安全工作组 (页面存档备份,存于互联网档案馆)进行解决。 [6] [7]
另一个问题是没有合适的策略,XML在SOAP中的使用和WS-Security可能导致容易受到攻击。[8]