论文部分内容阅读
[摘 要] 本文主要研究如何充分利用XML的结构化优势,结合传统数字签名技术,实现粒度可选的数字签名。首先深入研究了XML数字签名的规范,XML数字签名的生成原理及验证方法。并利用跨平台的Java语言对基于WEB的XML电子定单实现粒度可选的数字签名,解析了基于Java的XML数字签名的通用实例,使其能够很方便的融入实际应用之中。
[关键词] XML 数字签名 RSA JAVA
一、引言
XML(eXtensible Markup Language,可扩展标记语言)是由W3C于1998年2月发布的一种标准,是SGML(Standard Generalized Markup Language,标准通用标记语言)的一个简化子集。XML作为一种描述数据的标记语言,以其强大的描述功能、可扩展性、结构化语义,以及平台无关性等特点,在互联网和分布式异构环境中成为主要的数据传输和交换载体,在电子商务等领域得到了广泛的应用。为了确保XML数据的安全性,尤其是数据的完整性、可验证性和不可抵赖性,XML数字签名技术应运而生。
XML数字签名与传统的数字签名技术相比,并没有技术上的飞跃或本质上的不同。XML数字签名技术同样基于目前广泛使用的公共密钥体系(Public Key Infrastructure,PKI),用户基于某种非对称加密算法,例如:RSA、DSA,用私钥对要签署的数据签名,然后接受方用签名者的公钥对签名进行校验。但不同的是,传统的数字签名技术一般采用整体式签名,或基于OLE的对象链接嵌入式签名。传统的数字签名技术很难支持电子文档的多人批复签名,也不支持对电子文档的部分签名。XML数字签名较好地解决了上述问题。XML数字签名充分利用了XML语言本身强大的表达能力和扩展能力,不仅可以像传统的数字签名技术一样对整个文档签名,还可以实现在较细的粒度上对文档的特定部分进行签名,且支持多重签名。
二、XML数字签名规范
由IETF(Internet Engineering Task Force)和W3C共同组建的XML Signature工作组在2001年8月20日公布了XML数字签名的推荐版本。W3C将XML数字签名解释为:定义一种与XML语法兼容的数字签名语法描述规范,描述数字签名本身和签名的生成与验证过程。作为一个安全有效的数字签名方案,该规范提供了数字签名的完整性(Integrity)、签名确认(Authentication)和不可抵赖性(None repudiation)。其规范框架及产生流程如图1所示:
根据签名元素和被签名对象之间的关系,XML数字签名有三种签名方式:
1.封装式签名(Enveloping Signature),被签名数据被封装在XML签名元素的内部,元素类似于一个信封,将签名的数据封在里面。
2.嵌入式签名(Enveloped Signature),元素本身被嵌入到被签名数据中,与封装式相反,被签名的数据充当了包含签名的“信封”。
3.分离式签名(Detached Signature),元素和被签名数据是彼此分离的,两者之间不存在包含和被包含的关系。被签名的数据可以是独立的外部文档,也可以是跟Signature元素位于同一XML文档内的并列的兄弟元素。
三、XML数字签名的实现
1.XML数字签名生成。自从XML数字签名规范发布以来,很多组织机构进行了研究并提供了具体的实现。例如,IBM的AlphaWorks小组开发了XML安全套件(XML Security Suite),除了提供XML数字签名的实现外,还包括了XML的访问控制、XML加密等功能。NEC专门提供了XML-Signature Software Library对XML数字签名进行支持。但是XML安全或数字签名套件,很难满足在各种应用程序中对各种各样实际的XML文档进行灵活的签名应用。本文将XML数字签名与跨平台的Java语言相结合,对XML电子订单文档实现粒度可选的数字签名。实现步骤如下:
(1)生成密钥对。对于一个用户来说,如果要进行数字签名,那么他必须有一对属于自己的密钥对(私钥和公钥)。在实际应用系统中,密钥对通常是由CA预先生成的并存储在服务器密钥库中,私钥自己保存和公钥公开。我们利用Java中提供的工厂类KeyPairGenerator,通过其中的genKeyPair()方法生成密钥对。
KeyPairGenerator KPG=KeyPairGenerator.getInstance("RSA"); //---创建密钥对生成器---
KPG.initialize(1024);//---初始化密钥生成器---
KeyPair KP=KPG.genKeyPair();//---生成密钥对---
(2)加载解析XML文档转换为DOM对象。用DOM解析XML文档操作比较简便,先将XML文档读入内存,在内存中建立起一棵DOM文档树,然后通过对内存中DOM文档树的操作来完成对XML文档的操作。加载解析XML文档并取得根元素的代码如下:
DocumentBuilderFactory userDBF=DocumentBuilderFactory.newInstance();//---建立一个解析器工厂---
DocumentBuilder userDB=userDBF.newDocumentBuilder(); //---获得一个DocumentBuilder对象,这个对象代表了具体的DOM解析器
Document doc=userDB.parse(new File("invoice.xml")); //---得到代表invoice.xml文件的文档对象
Element elementRoot=doc.getDocumentElement(); //---得到根元素---
然后通过Node结点对象的getChildNodes()方法获取DOM树中所需要的子节点。后面我们创建Reference元素对象、SignedInfo元素对象、KeyInfo元素对象、XMLSignature元素对象都要用到加载的DOM文档树。
(3)对XML文档中的节点进行可选性签名。对要签名的文档(或节点)用指定的算法进行转换。如下转换获得需要签名的节点:
descendant-or-self::creditcard
根据指定的算法对转换后的结果进行摘要计算,结果存入。JAVA中提供了比较成熟的计算摘要的算法,MessageDigest是工厂类,用静态方法getInstance()来生成对象,传入参数是String类型,用于指出计算摘要使用的算法。摘要计算的核心代码如下:
try{ MessageDigest MD=MessageDigest.getInstance("MD5");
MD.update(str.getBytes("UTF8"));
byte[] strMD5Byte=MD.digest();
return strMD5Byte;
}catch(Exception e){e.printStackTrace();}
III.收集各个参考对象元素,该元素包括: ,和,建立。
IV.建立元素并进行规范化处理后签名。读取私钥并签名的关键代码:
FileInputStream FIS=new FileInputStream("RSAPriKey.dat"); //---读取私钥---
Signature signature=Signature.getInstance("MD5WithRSA"); //---获取Signature对象---
signature.initSign(RSAPK); //---初始化Signature对象---
signature.update(mydata.getBytes("UTF8")); //---传入要签名的数据---
byte[] signeddata=signature.sign();//---用私钥作签名---
(4)按照中指定的算法对元素进行签名操作,将签名结果存入节点。建立元素,该元素包括、。最后,将各个元素添加入XML文档,生成XML签名文档。运用JAVA语言对下图中的XML电子订单文档实现了XML文档节点可选性的数字签名,结合上述签名过程解析,对结点进行签名的实现结果如下图所示:
2.XML数字签名验证。XML数字签名的校验过程分为两部分进行,参考校验(Reference Validation)和签名校验(Signature Validation)。参考校验的目的是确保被签署对象没有被做任何的修改,验证在每个元素的元素中进行;而签名校验的目的则是保证签署人身份的真实性,验证利用元素计算得来的签名。
(1)对签名校验(参考校验)。对签名校验通过计算元素中的每一个元素,与元素中已包含的摘要值进行比较。
(2)对签名校验(签名校验)。对的签名校验,用指定的算法重新计算元素的签名值,将生成的值和中已有的签名值进行比较。
当上述两步都成功时,该XML数字签名的校验才算通过。
四、结束语
随着XML的广泛应用,XML数据的安全问题已成为关注的焦点。本文主要对XML数字签名规范,XML数字签名的生成与验证过程进行了系统的研究。并结合XML文档的结构优势和RSA算法的安全性,利用跨平台的Java语言对XML文档实现粒度可选的数字签名,并详细解析了实现过程及关键代码,使其能够很方便的融入实际应用之中。在文档部分签名的实际应用当中具有一定的借鉴意义。
参考文献:
[1]丁跃潮 张 涛:XML实用教程[M].北京:北京大学出版社,2006
[2]韦琳娜 张连宽等:XML数字签名和传统数字签名的对比研究[J].信息技术与标准化,2004,10
[3]张 勇 冯玉才:XML数字签名技术及其在Java中的具体实现[J].计算机应用,2003,9
[4]http://www.w3.org/TR/2008/PER-xmldsig-core-20080326/
[5]郭竞乐 赵正德等:XML 数字签名技术的研究与实现[J].计算机工程与设计,2005,05
[6]于国良 韩文报:XML的签名[J].计算机工程与应用,2006,07
[关键词] XML 数字签名 RSA JAVA
一、引言
XML(eXtensible Markup Language,可扩展标记语言)是由W3C于1998年2月发布的一种标准,是SGML(Standard Generalized Markup Language,标准通用标记语言)的一个简化子集。XML作为一种描述数据的标记语言,以其强大的描述功能、可扩展性、结构化语义,以及平台无关性等特点,在互联网和分布式异构环境中成为主要的数据传输和交换载体,在电子商务等领域得到了广泛的应用。为了确保XML数据的安全性,尤其是数据的完整性、可验证性和不可抵赖性,XML数字签名技术应运而生。
XML数字签名与传统的数字签名技术相比,并没有技术上的飞跃或本质上的不同。XML数字签名技术同样基于目前广泛使用的公共密钥体系(Public Key Infrastructure,PKI),用户基于某种非对称加密算法,例如:RSA、DSA,用私钥对要签署的数据签名,然后接受方用签名者的公钥对签名进行校验。但不同的是,传统的数字签名技术一般采用整体式签名,或基于OLE的对象链接嵌入式签名。传统的数字签名技术很难支持电子文档的多人批复签名,也不支持对电子文档的部分签名。XML数字签名较好地解决了上述问题。XML数字签名充分利用了XML语言本身强大的表达能力和扩展能力,不仅可以像传统的数字签名技术一样对整个文档签名,还可以实现在较细的粒度上对文档的特定部分进行签名,且支持多重签名。
二、XML数字签名规范
由IETF(Internet Engineering Task Force)和W3C共同组建的XML Signature工作组在2001年8月20日公布了XML数字签名的推荐版本。W3C将XML数字签名解释为:定义一种与XML语法兼容的数字签名语法描述规范,描述数字签名本身和签名的生成与验证过程。作为一个安全有效的数字签名方案,该规范提供了数字签名的完整性(Integrity)、签名确认(Authentication)和不可抵赖性(None repudiation)。其规范框架及产生流程如图1所示:
根据签名元素和被签名对象之间的关系,XML数字签名有三种签名方式:
1.封装式签名(Enveloping Signature),被签名数据被封装在XML签名元素的内部,
2.嵌入式签名(Enveloped Signature),
3.分离式签名(Detached Signature),
三、XML数字签名的实现
1.XML数字签名生成。自从XML数字签名规范发布以来,很多组织机构进行了研究并提供了具体的实现。例如,IBM的AlphaWorks小组开发了XML安全套件(XML Security Suite),除了提供XML数字签名的实现外,还包括了XML的访问控制、XML加密等功能。NEC专门提供了XML-Signature Software Library对XML数字签名进行支持。但是XML安全或数字签名套件,很难满足在各种应用程序中对各种各样实际的XML文档进行灵活的签名应用。本文将XML数字签名与跨平台的Java语言相结合,对XML电子订单文档实现粒度可选的数字签名。实现步骤如下:
(1)生成密钥对。对于一个用户来说,如果要进行数字签名,那么他必须有一对属于自己的密钥对(私钥和公钥)。在实际应用系统中,密钥对通常是由CA预先生成的并存储在服务器密钥库中,私钥自己保存和公钥公开。我们利用Java中提供的工厂类KeyPairGenerator,通过其中的genKeyPair()方法生成密钥对。
KeyPairGenerator KPG=KeyPairGenerator.getInstance("RSA"); //---创建密钥对生成器---
KPG.initialize(1024);//---初始化密钥生成器---
KeyPair KP=KPG.genKeyPair();//---生成密钥对---
(2)加载解析XML文档转换为DOM对象。用DOM解析XML文档操作比较简便,先将XML文档读入内存,在内存中建立起一棵DOM文档树,然后通过对内存中DOM文档树的操作来完成对XML文档的操作。加载解析XML文档并取得根元素的代码如下:
DocumentBuilderFactory userDBF=DocumentBuilderFactory.newInstance();//---建立一个解析器工厂---
DocumentBuilder userDB=userDBF.newDocumentBuilder(); //---获得一个DocumentBuilder对象,这个对象代表了具体的DOM解析器
Document doc=userDB.parse(new File("invoice.xml")); //---得到代表invoice.xml文件的文档对象
Element elementRoot=doc.getDocumentElement(); //---得到根元素---
然后通过Node结点对象的getChildNodes()方法获取DOM树中所需要的子节点。后面我们创建Reference元素对象、SignedInfo元素对象、KeyInfo元素对象、XMLSignature元素对象都要用到加载的DOM文档树。
(3)对XML文档中的节点进行可选性签名。对要签名的文档(或节点)用指定的算法进行转换。如下转换获得需要签名的
根据
try{ MessageDigest MD=MessageDigest.getInstance("MD5");
MD.update(str.getBytes("UTF8"));
byte[] strMD5Byte=MD.digest();
return strMD5Byte;
}catch(Exception e){e.printStackTrace();}
III.收集各个参考对象
IV.建立
FileInputStream FIS=new FileInputStream("RSAPriKey.dat"); //---读取私钥---
Signature signature=Signature.getInstance("MD5WithRSA"); //---获取Signature对象---
signature.initSign(RSAPK); //---初始化Signature对象---
signature.update(mydata.getBytes("UTF8")); //---传入要签名的数据---
byte[] signeddata=signature.sign();//---用私钥作签名---
(4)按照
2.XML数字签名验证。XML数字签名的校验过程分为两部分进行,参考校验(Reference Validation)和签名校验(Signature Validation)。参考校验的目的是确保被签署对象没有被做任何的修改,验证在每个
(1)对
(2)对
当上述两步都成功时,该XML数字签名的校验才算通过。
四、结束语
随着XML的广泛应用,XML数据的安全问题已成为关注的焦点。本文主要对XML数字签名规范,XML数字签名的生成与验证过程进行了系统的研究。并结合XML文档的结构优势和RSA算法的安全性,利用跨平台的Java语言对XML文档实现粒度可选的数字签名,并详细解析了实现过程及关键代码,使其能够很方便的融入实际应用之中。在文档部分签名的实际应用当中具有一定的借鉴意义。
参考文献:
[1]丁跃潮 张 涛:XML实用教程[M].北京:北京大学出版社,2006
[2]韦琳娜 张连宽等:XML数字签名和传统数字签名的对比研究[J].信息技术与标准化,2004,10
[3]张 勇 冯玉才:XML数字签名技术及其在Java中的具体实现[J].计算机应用,2003,9
[4]http://www.w3.org/TR/2008/PER-xmldsig-core-20080326/
[5]郭竞乐 赵正德等:XML 数字签名技术的研究与实现[J].计算机工程与设计,2005,05
[6]于国良 韩文报:XML的签名[J].计算机工程与应用,2006,07