摘 要: 使用JAVA語言及相應(yīng)的軟件包,按照XKMS服務(wù)規(guī)范,建立XKMS服務(wù)模型,解決在電子病歷系統(tǒng)中涉及PKI系統(tǒng)的密鑰服務(wù)問題。
關(guān)鍵詞: XKMS XML語言 公鑰體系認(rèn)證PKI 電子病歷
電子病歷是以電子化方式管理的有關(guān)個(gè)人健康狀態(tài)和醫(yī)療保健行為的信息。本文所述的電子病歷是基于可擴(kuò)展標(biāo)記語言XML(Extensible Markup Language1.0)技術(shù)實(shí)現(xiàn)的。電子病歷的安全性問題涉及完整性、非否認(rèn)性、機(jī)密性等,這些問題都需要PKI系統(tǒng)的支持。本文將以一個(gè)簡(jiǎn)單示例介紹XKMS(XML Key Management Specification,XML密鑰管理規(guī)范)的模型實(shí)現(xiàn),實(shí)現(xiàn)一個(gè)請(qǐng)求公鑰的服務(wù),為電子病歷XML文檔的加密和簽名提供基于公鑰體系結(jié)構(gòu)PKI(Public Key Infrastructure)的XKMS服務(wù)基礎(chǔ)。
1 XKMS概述
在加強(qiáng)Web業(yè)務(wù)的安全性方面功不可沒。但從技術(shù)層面講,它要求每個(gè)用戶和應(yīng)用程序都要驗(yàn)證與之通信的每個(gè)用戶的身份,以確保對(duì)方的身份真實(shí)有效。實(shí)際上PKI將所有的信任決定都拋給了用戶,這要求復(fù)雜的程序庫和配置信息。由于PKI的部署過于復(fù)雜繁瑣,成本昂貴,因此一直沒有得到普及應(yīng)用。
XML簽名規(guī)范和加密規(guī)范規(guī)定了如何簽名和加密XML文檔,這有助于執(zhí)行關(guān)鍵任務(wù)的應(yīng)用程序使用基于XML的Web服務(wù)。在處理數(shù)字簽名和加密文檔時(shí)要使用PKI。為方便PKI與XML應(yīng)用程序以及使用這些程序的Web服務(wù)進(jìn)行集成,Microsoft、Verisign和WebMethods共同發(fā)起,由W3C發(fā)布了XKMS。XKMS的目標(biāo)就是解決PKI的這些問題。XKMS綜合了XML的互操作性和PKI的安全性,提供了基于PKI保密應(yīng)用程序的一個(gè)簡(jiǎn)單方法。應(yīng)用程序可以簡(jiǎn)單地將所有PKI處理程序任務(wù)委托給某個(gè)第三方信任服務(wù),而不是由自己對(duì)復(fù)雜的PKI函數(shù)進(jìn)行編碼,這樣就可以將工作重點(diǎn)集中在業(yè)務(wù)邏輯上。
XKMS簡(jiǎn)化了XML簽名和加密機(jī)制在XML應(yīng)用程序中的使用。XKMS將PKI協(xié)議和數(shù)據(jù)格式替換成基于XML的協(xié)議,使用XML詞匯來表示PKI并且支持SOAP消息和WSDL,使得XKMS服務(wù)對(duì)于平臺(tái)、供應(yīng)商和傳輸協(xié)議都是中立的,能夠平穩(wěn)地適應(yīng)Web服務(wù)的開發(fā)環(huán)境等。XKMS主要應(yīng)用在客戶對(duì)客戶、應(yīng)用服務(wù)器對(duì)客戶、服務(wù)器對(duì)服務(wù)器等環(huán)境中,信任的決定由一個(gè)公共的服務(wù)器完成,XKMS客戶僅需配置服務(wù)器的URI地址和服務(wù)器用來簽名答復(fù)的證書。使用不同的URI,可支持不同的信任模型。XKMS的請(qǐng)求/響應(yīng)都是封裝在SOAP請(qǐng)求/響應(yīng)中的。
2 XKMS內(nèi)容
XKMS由XML密鑰信息服務(wù)規(guī)范(XKISS)和XML密鑰注冊(cè)服務(wù)規(guī)范(XKRSS)組成。XKISS負(fù)責(zé)處理與XML簽名和加密相關(guān)的公鑰處理及驗(yàn)證;XKRSS則用于對(duì)密鑰對(duì)進(jìn)行注冊(cè)。
XKISS服務(wù)主要支持定位服務(wù)和驗(yàn)證服務(wù)二種操作。利用定位服務(wù)可以基于標(biāo)識(shí)符信息來定位和檢索已經(jīng)注冊(cè)的公鑰。在XML簽名環(huán)境中,<ds:KeyInfo>元素使服務(wù)可以對(duì)數(shù)字簽名進(jìn)行驗(yàn)證,在XML加密環(huán)境中,<ds:KeyInfo>元素則指定了用于對(duì)文檔進(jìn)行加密的密鑰信息,<ds:KeyInfo>元素構(gòu)成了這二大密碼學(xué)功能的基礎(chǔ)。定位服務(wù)能夠解析<ds:KeyInfo>元素并向客戶提供所需的公鑰信息。定位服務(wù)僅限于檢索而不能進(jìn)行驗(yàn)證。驗(yàn)證服務(wù)能夠驗(yàn)證密鑰對(duì)標(biāo)識(shí)符信息的綁定和有效性狀態(tài)。
XKRSS的目的是為了響應(yīng)一個(gè)完整的、基于XML的密鑰生命周期管理協(xié)議的需求,它支持四種操作,即密鑰的注冊(cè)、重發(fā)、取消和恢復(fù)。
XKMS目前最新的工作草案是2004年4月發(fā)布的(見http://www.w3.org/TR/2004/CR-xkms2-20040405),其中定義了具體的XKMS語法和元素。
3 實(shí)現(xiàn)過程
本文示例使用JAVA語言,利用JAXM(Java API for XML Messaging)軟件包和Apache Axis 1.1工程,在Jakarta Tomcat5服務(wù)器上簡(jiǎn)單演示XKMS中的一種LocateRequest服務(wù)。JAXM使用JAVA平臺(tái)進(jìn)行XML消息通信。AXIS是Apache的一個(gè)開放源代碼項(xiàng)目,是基于JAVA、SOAP規(guī)范的Web服務(wù)的實(shí)現(xiàn),它是目前比較出色的SOAP Web容器。Tomcat也是Apache的一個(gè)開放源代碼項(xiàng)目,是一個(gè)優(yōu)秀的Servlet/JSP容器。
3.1 客戶端
在客戶端程序中,按照XKMS規(guī)范格式,生成一個(gè)簡(jiǎn)單的XKMS請(qǐng)求的SOAP消息,請(qǐng)求內(nèi)容是定位一個(gè)使用者在PKI密鑰庫中的公鑰??蛻舳顺绦蛉缦拢?br />
public class Request {
public static void main(String[] args) {
try {
SOAPConnectionFactory scFactory=SOAPConnection-Factory.newInstance( );
SOAPConnection con=scFactory.createConnection( );
//創(chuàng)建SOAP連接
MessageFactory factory=MessageFactory.newInstance( );
SOAPMessage message=factory.createMessage( );
//創(chuàng)建消息
SOAPPart soapPart=message.getSOAPPart( );//獲取SOAPPart對(duì)象
SOAPEnvelope envelope=soapPart.getEnvelope( );
//獲取SOAPEnvelope對(duì)象
SOAPBody body=envelope.getBody( );//獲取SOAPBody對(duì)象
Name NLocate=envelope.createName(″LocateRequest″,
″xkms″,″http://www.w3.org/TR/CR-xkms2-20040405″);
//創(chuàng)建LocateRequest元素
SOAPElement Locate=body.addBodyElement(NLocate);
//添加LocateRequest元素
//根據(jù)XKMS格式創(chuàng)建XML元素及內(nèi)容,代碼省略…,創(chuàng)建的內(nèi)容結(jié)果見下面的請(qǐng)求信息
URLEndpoint endpoint=new URLEndpoint(//創(chuàng)建
//URLEndpoint對(duì)象
″http://localhost:9999/axis/services/XKMSServices″);
SOAPMessage response=con.call(message, endpoint);
//發(fā)送請(qǐng)求消息,接收響應(yīng)消息
con.close( );
response.writeTo(System.out);//顯示接收到的消息
啟用Apache AXIS 的TCPMonitor收到發(fā)送的SOAP消息,如下:
在上面的SOAP消息中,<soapenv:Body>元素中的內(nèi)容就是XKMS的請(qǐng)求信息,以<xkms:LocateRequest>元素為開始,請(qǐng)求返回一個(gè)用戶的公鑰名稱KeyName和公鑰值KeyValue。
3.2 服務(wù)器端
服務(wù)器端由Tomcat5+AXIS1.1構(gòu)成SOAP服務(wù)器,接收客戶端程序發(fā)送的消息,對(duì)消息進(jìn)行解析,提取請(qǐng)求信息和要求返回的信息,進(jìn)行處理,返回XKMS響應(yīng)。服務(wù)器端應(yīng)先建立PKI,這里使用Keytools工具,先建立一個(gè)用戶的RSA密鑰對(duì),存儲(chǔ)在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
服務(wù)器端接收請(qǐng)求消息,解析內(nèi)容,檢索密鑰庫中用戶的公鑰,進(jìn)行BASE64轉(zhuǎn)換,按照XKMS規(guī)范生成XKMS響應(yīng)消息,返回響應(yīng)消息。服務(wù)器端程序簡(jiǎn)示代碼如下:
public class XKMSServices {
public Document echoElements(Document elems) {
try {
MessageContext msgC=MessageContext.getCurrentContext( );
//獲取MessageContext對(duì)象
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);
//導(dǎo)入Keystore
KeyStore ks=KeyStore.getInstance(″JKS″);
ks.load(in,pass.toCharArray());
Certificate c=ks.getCertificate(alias);//獲取用戶數(shù)字證書
in.close( );
RSAPublicKey PKey=(RSAPublicKey)c.getPublicKey( );
//獲取用戶RSA公鑰
BigInteger BE=PKey.getPublicExponent( );//提取指數(shù)
BigInteger BM=PKey.getModulus( );//提取模數(shù)
byte[ ] bbe=BE.toByteArray( );
byte[ ] bbm=BM.toByteArray( );
sun.misc.BASE64Encoder encoder=new sun.misc.
BASE64Encoder( );//BSAE64轉(zhuǎn)換類
String sbe=encoder.encode(bbe);//BSAE64轉(zhuǎn)換
String sbm=encoder.encode(bbm);
DocumentBuilderFactory dbf=DocumentBuilderFactory.
newInstance( );//生成響應(yīng)消息
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語法格式創(chuàng)建響應(yīng)消息,代碼省略創(chuàng)建的內(nèi)容結(jié)果見下面的響應(yīng)SOAP消息
document.appendChild(root);
return document;//返回響應(yīng)
AXIS 的TCPMonitor接收到響應(yīng)的SOAP消息,省略SOAP頭形式如下:
在以上響應(yīng)消息中,<xkms:LocateResult>元素中包含了XKMS的響應(yīng)內(nèi)容,其中返回了用戶的公鑰名和公鑰值。<ds:Modulus>中包含了公鑰的模數(shù)的BSAE64編碼后的值,<ds:Exponent>中包含了公鑰的指數(shù)的BSAE64編碼后的值??蛻舳顺绦蚪邮盏巾憫?yīng)信息后,可對(duì)其進(jìn)行解析,提取出模數(shù)和指數(shù)字符串,進(jìn)行反BASE64編碼,就獲得了真正的模數(shù)和指數(shù)。這樣就可以對(duì)電子病歷XML文檔進(jìn)行加密處理。
4 總 結(jié)
XKMS目前仍處于發(fā)展階段,還將會(huì)進(jìn)一步修訂。實(shí)用過程中,還需開發(fā)緊密結(jié)合XKMS的API,將XKMS客戶端和服務(wù)器端的程序模塊化,實(shí)現(xiàn)XKISS和XKRSS中的其他服務(wù)。
參考文獻(xiàn)
1 Nagappan R,Skoczylas R著,龐太剛,陶程譯.JAVA Web服務(wù)開發(fā).北京:清華大學(xué)出版社,2004
2 Galbraith B著,吳旭超,王黎譯.WEB服務(wù)安全性高級(jí)編程. 北京:清華大學(xué)出版社,2003
3 徐迎曉.JAVA安全性編程實(shí)例.北京:清華大學(xué)出版社,2003
4 Dournaee B著,周永彬,賀也平,劉娟譯.XML安全基礎(chǔ).北京:清華大學(xué)出版社,2003