《电子技术应用》
您所在的位置:首页 > 通信与网络 > 设计应用 > 基于JAVA的XKMS服务简单模型实现
基于JAVA的XKMS服务简单模型实现
孟 翔1,3,薛万国2
1.中国科学技术大学,北京100039; 2.解放军总医院 计算机中心,北京100853;3.解放军
摘要: 使用JAVA语言及相应的软件包,按照XKMS服务规范,建立XKMS服务模型,解决在电子病历系统中涉及PKI系统的密钥服务问题。
Abstract:
Key words :

摘   要: 使用JAVA语言及相应的软件包,按照XKMS服务规范,建立XKMS服务模型,解决在电子病历系统中涉及PKI系统的密钥服务问题。
关键词: XKMS  XML语言  公钥体系认证PKI  电子病历

  电子病历是以电子化方式管理的有关个人健康状态和医疗保健行为的信息。本文所述的电子病历是基于可扩展标记语言XML(Extensible Markup Language1.0)技术实现的。电子病历的安全性问题涉及完整性、非否认性、机密性等,这些问题都需要PKI系统的支持。本文将以一个简单示例介绍XKMS(XML Key Management Specification,XML密钥管理规范)的模型实现,实现一个请求公钥的服务,为电子病历XML文档的加密和签名提供基于公钥体系结构PKI(Public Key Infrastructure)的XKMS服务基础。
1  XKMS概述
  在加强Web业务的安全性方面功不可没。但从技术层面讲,它要求每个用户和应用程序都要验证与之通信的每个用户的身份,以确保对方的身份真实有效。实际上PKI将所有的信任决定都抛给了用户,这要求复杂的程序库和配置信息。由于PKI的部署过于复杂繁琐,成本昂贵,因此一直没有得到普及应用。
  XML签名规范和加密规范规定了如何签名和加密XML文档,这有助于执行关键任务的应用程序使用基于XML的Web服务。在处理数字签名和加密文档时要使用PKI。为方便PKI与XML应用程序以及使用这些程序的Web服务进行集成,Microsoft、Verisign和WebMethods共同发起,由W3C发布了XKMS。XKMS的目标就是解决PKI的这些问题。XKMS综合了XML的互操作性和PKI的安全性,提供了基于PKI保密应用程序的一个简单方法。应用程序可以简单地将所有PKI处理程序任务委托给某个第三方信任服务,而不是由自己对复杂的PKI函数进行编码,这样就可以将工作重点集中在业务逻辑上。
  XKMS简化了XML签名和加密机制在XML应用程序中的使用。XKMS将PKI协议和数据格式替换成基于XML的协议,使用XML词汇来表示PKI并且支持SOAP消息和WSDL,使得XKMS服务对于平台、供应商和传输协议都是中立的,能够平稳地适应Web服务的开发环境等。XKMS主要应用在客户对客户、应用服务器对客户、服务器对服务器等环境中,信任的决定由一个公共的服务器完成,XKMS客户仅需配置服务器的URI地址和服务器用来签名答复的证书。使用不同的URI,可支持不同的信任模型。XKMS的请求/响应都是封装在SOAP请求/响应中的。
2  XKMS内容
  XKMS由XML密钥信息服务规范(XKISS)和XML密钥注册服务规范(XKRSS)组成。XKISS负责处理与XML签名和加密相关的公钥处理及验证;XKRSS则用于对密钥对进行注册。
  XKISS服务主要支持定位服务和验证服务二种操作。利用定位服务可以基于标识符信息来定位和检索已经注册的公钥。在XML签名环境中,<ds:KeyInfo>元素使服务可以对数字签名进行验证,在XML加密环境中,<ds:KeyInfo>元素则指定了用于对文档进行加密的密钥信息,<ds:KeyInfo>元素构成了这二大密码学功能的基础。定位服务能够解析<ds:KeyInfo>元素并向客户提供所需的公钥信息。定位服务仅限于检索而不能进行验证。验证服务能够验证密钥对标识符信息的绑定和有效性状态。
  XKRSS的目的是为了响应一个完整的、基于XML的密钥生命周期管理协议的需求,它支持四种操作,即密钥的注册、重发、取消和恢复。
  XKMS目前最新的工作草案是2004年4月发布的(见http://www.w3.org/TR/2004/CR-xkms2-20040405),其中定义了具体的XKMS语法和元素。
3  实现过程
  本文示例使用JAVA语言,利用JAXM(Java API for XML Messaging)软件包和Apache Axis 1.1工程,在Jakarta Tomcat5服务器上简单演示XKMS中的一种LocateRequest服务。JAXM使用JAVA平台进行XML消息通信。AXIS是Apache的一个开放源代码项目,是基于JAVA、SOAP规范的Web服务的实现,它是目前比较出色的SOAP Web容器。Tomcat也是Apache的一个开放源代码项目,是一个优秀的Servlet/JSP容器。
3.1 客户端
  在客户端程序中,按照XKMS规范格式,生成一个简单的XKMS请求的SOAP消息,请求内容是定位一个使用者在PKI密钥库中的公钥。客户端程序如下:
public class Request {
   public static void main(String[] args) {
      try {
  SOAPConnectionFactory scFactory=SOAPConnection-Factory.newInstance( );
  SOAPConnection con=scFactory.createConnection( );
                  //创建SOAP连接
  MessageFactory factory=MessageFactory.newInstance( );
  SOAPMessage message=factory.createMessage( );
                   //创建消息
  SOAPPart soapPart=message.getSOAPPart( );//获取SOAPPart对象
  SOAPEnvelope envelope=soapPart.getEnvelope( );
                   //获取SOAPEnvelope对象
  SOAPBody body=envelope.getBody( );//获取SOAPBody对象
  Name NLocate=envelope.createName(″LocateRequest″,
  ″xkms″,″http://www.w3.org/TR/CR-xkms2-20040405″);
                 //创建LocateRequest元素
  SOAPElement Locate=body.addBodyElement(NLocate);
                 //添加LocateRequest元素
    //根据XKMS格式创建XML元素及内容,代码省略…,创建的内容结果见下面的请求信息
  URLEndpoint endpoint=new URLEndpoint(//创建
                  //URLEndpoint对象
  ″http://localhost:9999/axis/services/XKMSServices″);
  SOAPMessage response=con.call(message, endpoint);
                  //发送请求消息,接收响应消息
  con.close( );
  response.writeTo(System.out);//显示接收到的消息
  启用Apache AXIS 的TCPMonitor收到发送的SOAP消息,如下:

  在上面的SOAP消息中,<soapenv:Body>元素中的内容就是XKMS的请求信息,以<xkms:LocateRequest>元素为开始,请求返回一个用户的公钥名称KeyName和公钥值KeyValue。
3.2 服务器端
  服务器端由Tomcat5+AXIS1.1构成SOAP服务器,接收客户端程序发送的消息,对消息进行解析,提取请求信息和要求返回的信息,进行处理,返回XKMS响应。服务器端应先建立PKI,这里使用Keytools工具,先建立一个用户的RSA密钥对,存储在Keystore中,以便使用。
  keytool-genkey-alias mengxiang-keyalg RSA-dname ″CN=301,OU=301,O=301,L=HaiDian,S=BeiJing,C=CN″-keypass password-keystore KeyStore-storepass password-storetype JKS
服务器端接收请求消息,解析内容,检索密钥库中用户的公钥,进行BASE64转换,按照XKMS规范生成XKMS响应消息,返回响应消息。服务器端程序简示代码如下:
  public class XKMSServices {
  public Document echoElements(Document elems) {
try {
  MessageContext msgC=MessageContext.getCurrentContext( );
             //获取MessageContext对象
  Message request=msgC.getRequestMessage( );//获取消息
  SOAPPart sp=request.getSOAPPart( );
  SOAPEnvelope se=sp.getEnvelope( );
  SOAPBody sb=se.getBody( );
  Iterator it1=sb.getChildElements( );//遍历元素,提取信息
  FileInputStream in=new FileInputStream(name);
               //导入Keystore
  KeyStore ks=KeyStore.getInstance(″JKS″);
  ks.load(in,pass.toCharArray());
  Certificate c=ks.getCertificate(alias);//获取用户数字证书
  in.close( );
  RSAPublicKey PKey=(RSAPublicKey)c.getPublicKey( );
              //获取用户RSA公钥
  BigInteger BE=PKey.getPublicExponent( );//提取指数
  BigInteger BM=PKey.getModulus( );//提取模数
  byte[ ] bbe=BE.toByteArray( );
  byte[ ] bbm=BM.toByteArray( );
  sun.misc.BASE64Encoder encoder=new sun.misc.
  BASE64Encoder( );//BSAE64转换类
  String sbe=encoder.encode(bbe);//BSAE64转换
  String sbm=encoder.encode(bbm);
  DocumentBuilderFactory dbf=DocumentBuilderFactory.
          newInstance( );//生成响应消息
  DocumentBuilder db=dbf.newDocumentBuilder( );
  document=db.newDocument( );
  Element root=document.createElement(″xkms:LocateResult″);
  root.setAttribute(″xmlns:ds″,″http://www.w3.org/2000/09/
     xmldsig#″);
      //按照XKMS语法格式创建响应消息,代码省略创建的内容结果见下面的响应SOAP消息
  document.appendChild(root);
  return document;//返回响应
  AXIS 的TCPMonitor接收到响应的SOAP消息,省略SOAP头形式如下:

  在以上响应消息中,<xkms:LocateResult>元素中包含了XKMS的响应内容,其中返回了用户的公钥名和公钥值。<ds:Modulus>中包含了公钥的模数的BSAE64编码后的值,<ds:Exponent>中包含了公钥的指数的BSAE64编码后的值。客户端程序接收到响应信息后,可对其进行解析,提取出模数和指数字符串,进行反BASE64编码,就获得了真正的模数和指数。这样就可以对电子病历XML文档进行加密处理。
4  总  结
  XKMS目前仍处于发展阶段,还将会进一步修订。实用过程中,还需开发紧密结合XKMS的API,将XKMS客户端和服务器端的程序模块化,实现XKISS和XKRSS中的其他服务。
参考文献
1   Nagappan R,Skoczylas R著,庞太刚,陶程译.JAVA Web服务开发.北京:清华大学出版社,2004
2   Galbraith B著,吴旭超,王黎译.WEB服务安全性高级编程. 北京:清华大学出版社,2003
3   徐迎晓.JAVA安全性编程实例.北京:清华大学出版社,2003
4   Dournaee B著,周永彬,贺也平,刘娟译.XML安全基础.北京:清华大学出版社,2003

此内容为AET网站原创,未经授权禁止转载。