什么是数字签名?
数字签名就是在信息的后面加上一段内容,可以证明信息没有被修改过。
那么怎么做到呢?
发送方对信息做一个hash计算得到一个hash值(注意,这个过程是不可逆的,也就是说无法通过hash值得出原来的信息内容)。在把信息发送出去时,把这个hash值用私钥加密后做为一个数字签名和信息一起发出去。
接收方在收到信息后,会重新计算信息的hash值,并和信息所附带的hash值(用公钥解密后)进行对比,如果一致,就说明信息的内容没有被修改过,因为这里hash计算可以保证不同的内容一定会得到不同的hash值,所以只要内容一被修改,根据信息内容计算的hash值就会变化。
什么是XML数字签名?
概要
XML Signature是一个定义数字签名的XML语法的W3C推荐标准。XML具有更好的可扩展性,为签名XML文档做了调整。XML Signature在许多Web技术中使用,如SOAP、SAML等。
XML签名为任何数据提供了完整性、消息认证、以及签名者认证服务。
XML数字签名可以应用于任何数据对象 ( 包括 XML 文档 ),也可以应用于一个或多个资源文件,或者资源文件的子集。
XML数字签名使用非对称加密,来保证数据来源和内容的正确,XML数据通过签名后,就无法被修改了。签名是由XML文档的所有或部分hash生成的摘要信息再加密而生成的,hash方式一般有md5和sha1。
因为XML文档中有不同的缩进和空格,所以需要规范化函数(canonicalizationMethod)先对文党进行处理,去除空格和其他格式,将XML数据简化为最简单的格式。为什么这很重要?因为一字之差就会生成两个不同的hash值。最后,使用签名转换来加密hash值。
这个XML电子签名使用了非对称加密和规范化函数,并且通常包含签名它的公钥。
电子签名有三种不同的形式:
- 1.包封式签名:签名被封装在被签名的XML文档中
- 2.签名封装被签名的XML文中
- 3.分离式签名:被签名的XML文档和签名是分开的
XML的数字签名格式
在http://www.w3.org/2000/09/xmldsig#命名空间下,XML签名包含了Signature元素。它的基本结构如下:
<Signature> <SignedInfo> <CanonicalizationMethod/> 规范化方法,用于去除空格和其他格式 <SignatureMethod/> (<Reference (URI)?> (<Transforms/>)? <DigestMethod/> <DigestValue/> </Reference>)+ </SignedInfo> <SignatureValue/> (<KeyInfo/>)? (<Object ID?/>)* </Signature>
举例
使用签名被封装在被签名XML中的方式
需要被签名的XML文档如下:
<license> <test>hello world</test> </license>
签名后的XML:
<license> <test>hello world</test> [s01]<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> [s02]<ds:SignedInfo> [s03]<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11"/> [s04]<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> [s05]<ds:Reference URI=""> [s06]<ds:Transforms> [s07]<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/> [s08]</ds:Transforms> [s09]<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> [s10]<ds:DigestValue>d+F/TTTxoF2Fk/knoTwHLqC7gqa+ETnTn84sNwx4c0Y=</ds:DigestValue> [s11]</ds:Reference> [s12]</ds:SignedInfo> [s13]<ds:SignatureValue>KdSti.....6OA==</ds:SignatureValue> [s14]<ds:KeyInfo> [s15a]<ds:KeyValue> [a15b]<ds:RSAKeyValue> [a15c]<ds:Modulus>nM95A0J.....+GQ==</ds:Modulus> [a15d]<ds:Exponent>AQAB</ds:Exponent> [a15e]</ds:RSAKeyValue> [a15f]</ds:KeyValue> [a16]</ds:KeyInfo> [a17]</ds:Signature> </license>
元素说明
-
SignedInfo
[s02-12]该元素的子元素包含有关所签名的内容以及签名方式的所有信息。签名算法实际上应用于该元素及其所有子元素以生成签名。 -
CanonicalizationMethod
[s03]该元素指定了用于SignedInfo元素以便将XML规范化的规范化(C14N)算法。 -
SignatureMethod
[s04]该元素指定了该签名的签名算法。这里的签名算法是带有RSA的SHA-256。 -
Reference
[s05-11]这些元素指定了将要签名的数据以及在哈希运算之前应当如何对该数据进行处理。URI属性(它表示统一资源标识符)标识要签名的数据,而Transforms元素(稍后描述)指定在进行哈希运算之前如何处理数据。在该示例中,我们将使用特殊的URI——空字符串,它指定包含签名的文档是要包含在签名中的数据。XML签名标准对Reference数据使用间接签名机制。该标准不是对Reference中的所有数据进行哈希运算然后加密哈希值,而是使用由Reference的DigestMethod元素所指定的算法对每个Reference的数据进行哈希运算,然后将哈希值存储到Reference的DigestValue元素中。接下来,对SignedInfo元素和它的所有子元素(包括Reference元素)进行哈希运算;哈希值被加密以生成签名。因此,您实际上是对Reference元素中所引用数据的哈希的哈希进行签名,但是该方案仍然可以保护数据的完整性。
**[s05]**Reference的这个可选 URI 属性标识要签名的数据对象。 在一个 Signature 中,至多可以对一个Reference省略该属性。(为了确保明确地匹配引用和对象, 要强加这个限制。)
[s06-08]该标识与transforms一起是签名者提供的描述, 其内容有关它们如何获得已编摘形式的已签名数据对象(即,已编摘的内容)。验证者还可能以另一种方法获得已编摘的内容,只要摘要验证这种方法。 -
Transforms
[s06-08]每个Reference元素都可以具有零个或更多个为它指定的转换。这些转换按照它们在XML中列出的顺序应用于该Reference的数据。转换使您可以在对Reference的数据进行哈希运算之前对该数据进行筛选或修改。在该示例中,我们将使用包封式签名转换,该转换选择了包含文档中除Signature元素以外的所有XML。我们必须从将被签名的数据中移除Signature元素,否则,当我们存储签名值时,可能会修改我们尝试签名的数据。 -
DigestMethod
**[s09-10]**DigestMethod 是在应用 Transforms(如果已经指定它)之后对数据应用以产生 DigestValue 的算法。DigestValue 的签名是将资源内容与签名者密钥绑定的机制。 -
SignatureValue
[s13]该元素包含通过签名SignedInfo元素及其所有子元素而计算得到的签名值。 -
KeyInfo
**[s14-16]**KeyInfo表示用于验证签名的密钥。标识机制可以包括证书、密钥名称和密钥协议算法。KeyInfo是可选的有两个原因。首先,签名者可能不希望向所有文档处理方披露任何密钥信息。为什么总要告诉人家?其次,该信息在应用程序上下文中可能是已知的,并且不需要明确表示。 由于KeyInfo在SignedInfo之外,所以如果签名者希望将密钥信息与签名绑定,那么Reference可以容易地将KeyInfo作为签名的一部分标识并将其包括在内。