XML数字签名及其.NET实现

XML数字签名及其.NET实现

一觉亮天

 

摘要:本文介绍了数字签名的原理和XML数字签名的标准。XML数字签名适应并且利用了XML的特点,除具有其他数字签名保证数据传输的真实性、完整性和不可否认性的功能外,更加适用于因特网和XML文档。最后给出了一个用.NET框架实现的对XML进行数字签名和验证的例子。

关键词:数字签名;XML数字签名;.NET框架

中图分类号:TP309 文献标识码:A

 

XML Digital Signature and its Implementation through .NET Framework

YiJiaoLiangTian

Abstract: In this article, concepts of DigitalSignature and specifications of XML Digital Signature are introduced. It bothaccount for and take advantage of features of XML, so XML Digital Signature notonly can ensure authenticity, data integrity and non-repudiation fortransferring data the same as other Digital Signatures, but also is verysuitable for Internet and XML. There are also examples of signing and verifyingXML document implemented through .NET framework.

Key words: Digital Signature; XML Digital Signature;.NET framework

 

1.引言

随着电子商务的不断发展,基于浏览器的安全机制对于小面额的商务事务应用来说足够了,但对对于大面额的商务事务和敏感信息交换方面显得不足。保证商务信息的保密性,就是要长期保证他们的真实性,数据完整性和不可否认性。在商务活动中满足这种需求的公认的方法是采用数字证书来对交换的信息进行加密和数字签名。XML语言的基于文本,语义丰富,结构化等特点,决定了其在商务事务中应用广泛。为了适应和利用XML数据的特点,两种新的安全技术被提出和设计,XML数字签名和XML加密。随着相应标准的完善,这两种技术也在逐步完善。XML数字签名是W3C(World Wide Web Consortium)IETF(Internet Engineering Task Force)共同的成果。本文简单介绍数字签名的原理和XML数字签名的特点和标准,并给出了一个.NET实现。

2.公钥加密和数字签名简介

公钥加密体系使用户能够在不安全的像Internet这样的网络上安全地交换数据,确保数据不被篡改和非法访问。公钥加密采用的加密数据的算法需要一对数,分别被称为公钥和私钥。数据交换的每一个参与者都具有这样一对数。公钥对所有希望交换信息的人都是公开的,私钥是受保护的保密的。虽然这一对数在数学上是相关的,但是在计算上是不能够通过公钥而推算出私钥的。

公钥加密的特点是,由公钥和私钥对中的一个加密的数据,只能由另一个解密。根据公钥加密的这个特点就可以确保数据交换的保密性。因为用接收者的公钥加密的数据,只能由持有相应私钥的接收者解密。即使数据被别人中途截获,没有正确的私钥,第三方也不能够解密数据。重要的是,采用这种方法,发送者和接收者之间不需要像在对称加密中那样交换除了数据以外的额外的保密数据。

由于公钥和私钥之间的特殊关系,采用公钥加密除了确保数据交换保密性外,还为公钥加密提供了另外的对称式加密所不具备的功能。就是确保了数据的真实性,完整性和不可否认性。通过这样一种机制,就能够实现类似纸上签名的数字签名。

为一个消息创建数字签名,被签名的数据通过一种公钥加密算法,以发送者的私钥作为参数来加密。因为以发送者私钥加密的数据只能够由发送者的公钥解密。因为只有发送者有私钥,如果数据能够通过发送者公钥的验证,那么数据一定是由相应的私钥签名的。

为了使签名有意义,验证者必须确定公钥确实是属于发送者的,否则冒名顶替者可能也会宣布他是发送者,假装他拥有公钥。由认证权威发行的证书,可以证明认证主体和他的公钥之间的对应关系。通过证书就能够确认公钥是否属于某发送者。

由于公钥加密算法性能效率方面的原因和安全方面的原因,通常不用私钥加密整个信息数据,而是对信息数据的被称为摘要的特征进行加密。摘要是通过不可逆的哈希算法计算出来的。因为哈希算法对源文档的任何改动都非常敏感,接收者可以根据源文的摘要来验证文档有没有被改变。另外,发送者通过用私钥加密摘要,可以使接收者能够验证发送者的真实性。用发送者的私钥加密的文档的摘要,可以作为这篇文档的数字签名,可以随同文档一起发送给接收者。接收者通过接收到的文档和发送者的公钥来验证签名。如果签名正确,接收者就可以确保收到信息的真实性和完整性。

3XML数字签名

31XML数字签名简介

XML数字签名是被设计为用于XML事务处理方面的数字签名。这个标准定义了对任意数据进行数字签名操作的纲要。同非XML数字签名一样,XML数字签名提供真实性,完整性和不可否认性的保证。同非XML相关的数字签名不一样的是,XML数字签名更加适合于因特网和XML文档。

XML数字签名的一个基本特征就是可以对XML树的一部分进行签名,而不是整个文档。有些XML文档可能由不同部门在不同时间完成不同部分,每个部分由责任部门来签名,是最合适不过的了。当只需要保证一个XML文档的某个部分的完整性,而其它部分可以随意更改的时候,XML数字签名的这个灵活性也非常有用。例如,当一个用户需要修改一篇已经签名的XML文档的时候,如果签名是针对整个文档的,那么这个用户对文档的任何改变将会使签名无效。

XML数字签名可以签名多种类型的资源。例如,不同字符集组成的数据(HTML),二进制数据(JPG图片文件),XML文档和XML文档的一部分。

进行数字签名需要被签名的数据是可以访问的。XML数字签名本身通常就表明了被签名对象的位置。被签名对象的位置可以非常灵活,可以由XML数字签名内的URI来引用,可以与XML数字签名在同一位置,可以嵌入到XML数字签名中。被签名对象还可以把数字签名嵌入到自身中。

32创建XML数字签名的步骤

1)决定待签名的资源。

可以通过URI来表示资源。例如:“http://www.superstar.com/apage.xml”。

2)计算每个资源的摘要。

XML数字签名中,每个参考资源通过<Reference>元素和它的位于<DigestValue>子元素中的摘要组成。并且由<DigestMethod>指定计算摘要的哈希算法。如下所示:

<Reference URI="http://www.superstar.com/apage.xml">

 <DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

 <DigestValue>t6lwx1rvGPO0vKtUup4NbeV38nF=</DigestValue>

</Reference>

<ReferenceURI="http://www.xuhxblog.com/bpage2.xml">

 <DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

 <DigestValue>p3274yuvQ9UKtUuv1MPfN76wG=</DigestValue>

</Reference>

3)集合各参考元素

通过<SignedInfo>元素集合各<Reference>元素。如下所示:

<SignedInfo Id="MyPage">

 <CanonicalizationMethod

   Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>

 <SignatureMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />

<Reference URI="http://www.superstar.com/apage.xml">

 <DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

 <DigestValue>t6lwx1rvGPO0vKtUup4NbeV38nF=</DigestValue>

</Reference>

<ReferenceURI="http://www.xuhxblog.com/bpage2.xml">

 <DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

 <DigestValue>p3274yuvQ9UKtUuv1MPfN76wG=</DigestValue>

</Reference>

</SignedInfo>

<CanonicalizationMethod>





元素表示用于规范化





<SignedInfo>





元素的算法。带有相同





XML





信息集合的数据流可能有不同的文本表示形式。例如空格表示方法的不同。为了避免不正确的验证结果,





XML





信息在进行数字签名之前,必须进行规范化。





<SignatureMethod>





元素用于表示产生数字签名值的算法。










4


进行签名 







计算





<SignedInfo>





元素的摘要,签名摘要,把签名值放到





<SignatureValue>





元素中。如下:







<SignatureValue>Wp0E1LE=</SignatureValue>





5


)添加密钥信息


如果要包含密钥信息的话,把它放到


<KeyInfo>





元素中。在下面例子中包含发送者的





X.509





证书。证书里面包含验证签名正确性所需要的发送者的公钥。







<KeyInfo>


 <X509Data>


  


<X509SubjectName>CN=Xu Hongxing,O=XMLSec,ST=OTTAWA,C=CA</X509SubjectName>


  


<X509Certificate>QjjO4jDDBl+gA...4tY</X509Certificate>


 </X509Data>


</KeyInfo>


6)包含进<Signature>元素内

<SignedInfo><SignatureValue><KeyInfo>元素放到<Signature>内。<Signature>元素就构成了XML数字签名。如下:

<?xml version="1.0"encoding="UTF-8"?>

<Signaturexmlns="http://www.w3.org/2000/09/xmldsig#">

<SignedInfo Id="foobar">

<CanonicalizationMethod

  Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>

<SignatureMethod

 Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1" />

<ReferenceURI="http://www.xuhxblog.com/apage1.xml">

 <DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

 <DigestValue>t6lwx1rvGPO0vKtUup4NbeV38nF=</DigestValue>

</Reference>

<ReferenceURI="http://www.xuhxblog.com/bpage2.xml">

 <DigestMethodAlgorithm="http://www.w3.org/2000/09/xmldsig#sha1" />

 <DigestValue>p3274yuvQ9UKtUuv1MPfN76wG=</DigestValue>

</Reference>

</SignedInfo>

<SignatureValue>Wp0E1LE=</SignatureValue>

<KeyInfo>

 <X509Data>

 <X509SubjectName>CN=Xu Hongxing,O=XMLSec </X509SubjectName>

 <X509Certificate>QjjO4jDDBl+gA...4tY</X509Certificate>

 </X509Data>

</KeyInfo>

</Signature>

33验证XML数字签名

下面简单描述一下验证XML数字签名的过程

1)验证<SignedInfo>元素。用<SignatureMethod >元素中标示的算法重新计算<SignedInfo>元素的摘要。应用公钥来验证<SignatureValue>元素中的内容是否正确。

2如果第一步通过了,重新计算 <SignedInfo>元素中参考的资源的摘要,同<Reference>元素中的摘要比较。

4.用.NET框架实现XML数字签名

41.NET框架加密模型简介

Microsoft.NET框架是微软推出的新的计算平台,XML在其中有非常广泛的应用。.NET框架提供了一整套加密服务的类库,包括对XML进行数字签名的解决方案。.NET框架提供许多标准加密算法的实现,例如用于公钥加密的RSACryptoServiceProvider。用.NET框架提供的加密服务的类,开发者不用考虑加密的很多细节问题。.NET框架加密模型采用面向流的方法实现加密,加密效率非常高,可以对数据进行多种操作而不需要提供中间存储。

42例子程序

第一个例子程序可以实现对XML文档进行数字签名,签名嵌入在待签名的XML文档中。第二个例子程序实现对被签名的XML文档的验证。程序采用.NET中的C#语言书写,由于篇幅原因省去了异常处理代码和类的声明代码,只提供完成功能的函数。根据这两个例子程序中的步骤和思想,可以很容易推广应用在其他类似的加密操作和签名操作中。

下面是对XML文档进行数字签名的代码。参数xmlKeyPair是包含公钥和私钥的XML字符串。.NET框架中有工具用来生成密钥和进行相关的操作,SN.EXE就是这样的工具。

void SignXmlDoc(string xmlKeyPair,XmlDocumentxmlDoc,XmlTextWriter writer)

{

  //创建加密服务提供者对象

 RSACryptoServiceProvider csp=new RSACryptoServiceProvider();

  //由通过 XML 字符串重新构造重新构造加密服务提供者对象

 csp.FromXmlString(xmlKeyPair);

  //创建XML签名对象

  SignedXml sxml=newSignedXml(xmlDoc);

  sxml.SigningKey =csp;

  //指定待签名文档的规范化方法

  sxml.SignedInfo.CanonicalizationMethod=

SignedXml.XmlDsigCanonicalizationUrl;

  //创建引用对象

  Reference r = newReference("");

  //指定签名包含在待签名的XML文档中

  r.AddTransform(newXmlDsigEnvelopedSignatureTransform(false));

  //向签名对象中添加引用

 sxml.AddReference(r);

  //计算数字签名

  sxml.ComputeSignature();

  XmlElement sig =sxml.GetXml();

  //把签名加入到文档中

 xmlDoc.DocumentElement.AppendChild(sig);

  //把签名过后的文档输出到writer对象中

 xmlDoc.WriteTo(writer);

  writer.Flush();

}

下面是验证对XML文档数字签名正确性的代码。参数xmlPubKey是只包含公钥的XML字符串。XmlDoc是待验证的XML文档,如果通过验证,函数返回真值,否则返回假值。

bool VerifyXmlDoc(string xmlPubKey,XmlDocument xmlDoc)

{

  //创建加密服务提供者对象

 RSACryptoServiceProvider csp = new RSACryptoServiceProvider();

  //由通过 XML 字符串重新构造加密服务提供者对象

csp.FromXmlString(xmlPubKey);

//创建XML签名对象

  SignedXml sxml = newSignedXml(xmlDoc);

  //得到签名元素的节点

  XmlNode dsig =xmlDoc.GetElementsByTagName("Signature",

   SignedXml.XmlDsigNamespaceUrl)[0];

 sxml.LoadXml((XmlElement)dsig);

  //验证签名是否正确,并且返回结果

  returnsxml.CheckSignature(csp);

}

 

5.结论

随着XML成为电子商务体系结构中的重要组成部分,我们需要可以信赖的,安全的XML消息来形成商务事务的基础。确立安全的事务处理其中一个关键是采用数字签名,来确保原始消息的真实性和完整性。XML数字签名是改进的数字签名标准。它既利用了XML的特点满足XML特殊要求,又利用XML语法来表示签名结果,能够简化与XML相关的应用的集成。

 

参考文献

[1]英宇,林琪,费广正.Microsoft .NET XML高级编程[M].北京:清华大学出版社,2002.

[2]李建忠.Microsoft.NET框架程序设计[M].北京:清华大学出版社,2003.

[3]陈月波.电子商务网站建设[M] .浙江:浙江大学出版社,2003.

[4]谢冬青,冷健.PKI原理与技术[M].北京:清华大学出版社,2004.

你可能感兴趣的:(.net,加密,xml,文档,reference)