针对清单3-1的XML病历文档,病人的个人信息是不希望其他人看见的,所以对这些信息进行加密,加密后用<EncryptedData>元素替换<PersonalInfo>元素得到加密后的XML文档,清单4-1给出加密后的XML片段。
<PersonalInfo>
<EncrytpedData Type=http://www.w3.org/2001/04/xmlenc#Content xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm=http://www.w3.org/2001/04/xmlenc#tripledes-cbc xmlns="" />
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmlsig#">
<EncryptedKey xmlns="">
<ds:KeyInfo>
<ds:KeyName>RSAKey</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue>
<EncryptedSymmetricKey>Nb4A43dH6…</EncryptedSymmetricKey>
<EncryptedSymmetricIV>RQsK1jlEBtV…</EncryptedSymmetricIV>
</CipherValue>
</CipherData>
</EncryptedKey>
</ds:KeyInfo>
<CipherData xmlns="">
<CipherValue>Hfrd1Pd0yVSGo6k…</CipherValue>
</CipherData>
</EncrytpedData>
</PersonalInfo>
清单4-1<PersonalInfo>加密后的文档片段
在清单中<EncryptionMethod>元素指定了加密的算法,< KeyInfo >元素指定的是密钥信息,其中< KeyName >元素是指RSA非对称密钥的名称,第一个<CipherData>下的<. CipherValue >元素指使用RSA的公钥加密3DES密钥后的密文。第二个<CipherData>下的<. CipherValue >元素指使用3DES算法加密原文档<PersonalInfo>元素后的密文。
五、NET环境下的程序实现
自从XML数字签名的规范发布以来,许多机构都对其进行深入研究并提供了解决方案,同时XML加密的规范也已经成型。但大多数签名与加密是基于Java平台的,包括IBM和NEC的签名库。为了打破Java“一统天下”的局面,本文采用C#语言在Visual Studio.Net 2003环境下实现XML电子病历的加密与签名。
微软公司在其.NET 2003平台中改进了XML的内核结构,对XML实现了完全的内部支持,可以使用其类库来编程。
1.XML Schema 检验的实现
在.NET Framework中,与XML Schema相关的类在 System.Xml.Schema下。
XmlTextReader reader = new XmlTextReader(flieName);
XmlValidatingReader objXValRead = new
XmlValidatingReader(reader);
objXValRead.ValidationType = ValidationType.Schema;
while(objXValRead.Read()){}
return true;
如果While语句为真,说明XML文档的结构符合Shema的描述。
2.XML加密的实现
在.NET Framework 中,与XML 加密相关的类集中在和System.Security.Cryptography 和System.xml命名空间下,所以程序必须包含这两个命名空间。
步骤1: 生成RSA密钥对
利用.NET Framework下的Cryptography.RSA类来生成RSA非对称密钥,并分别将私钥与公钥保存为XML文档:
RSA Key = RSA.Create();
strPrivateKeyXML = Key.ToXmlString(true);
srrPublicKeyXML = Key.ToXmlString(false);
XmlDocument privateKeyXML,,publicKeyXML = new XmlDocument();
privateKeyXML.LoadXml(strPrivateKeyXML);
publicKeyXML.LoadXml(srrPublicKeyXML);
步骤2 : 通过Xpath语句判断加密次数,逐个加密:
nodes = doc.SelectNodes(strXpath);
nodeCount = nodes.Count;
for(int i=0;i<nodeCount;i++)
{
XmlNode currentNode = nodes.Item(i);
// EncrypXMLString方法是加密的具体实现
XmlElement xmlEncryptElement =
EncrypXMLString(currentNode.InnerXml,strKeyName);
}
通过Xpath语句可能找到多个节点,下面的步骤介绍EncrypXMLString方法的内容。
步骤3 : 使用3DES算法对文档进行加密:
SymmetricAlgorithm CSP = new
TripleDESCryptoServiceProvider();
MemoryStream ms = new MemoryStream();
byte [] bty = Encoding.UTF8.GetBytes(strXmlString);
CryptoStream cs = new
CryptoStream(ms,CSP.CreateEncryptor(CSP.Key,CSP.IV),CryptoStreamMode.Write);
cs.Write(bty,0,bty.Length);
将XML文档片段读入字节数组,然后用3DES加密算法进行加密。
步骤4 : 使用RSA算法的公钥加密KEY与IV:
RSACryptoServiceProvider rsa = new
RSACryptoServiceProvider();
//从密钥信息获取RSA的密钥信息
rsa.FromXmlString(GetRSAPublicKey(strKeyName));
string strEncryptedSymmetricKey =
Convert.ToBase64String(rsa.Encrypt(CSP.Key,false));
string strEncryptedSymmetricIV =
Convert.ToBase64String(rsa.Encrypt(CSP.IV,false));
对3DES算法用到的KEY与IV用RSA算法加密。
步骤5 : 构建加密节点。
组装<EncryptedData><EncryptionMethod/><ds:KetInfo>等节点,程序较长在此省略。
3.XML解密的实现
解密与加密一样,也需要通过Xpath语句判断加密点的个数,然后使用循环语句逐个解密。
步骤1 : 使用RSA算法的私钥解密KEY与IV。
首先建立RSA和3DES的对象,并定位node元素:
rsa.FromXmlString(GetRSAPrivateKey(node.InnerText));
node=root.SelectSingleNode("descendant::EncryptedKey/CipherData/CipherValue/EncryptedSymmetricKey");
CSP.Key= rsa.Decrypt(Convert.FromBase64String(node.InnerText),true);
node=root.SelectSingleNode("descendant::EncryptedKey/CipherData/CipherValue/EncryptedSymmetricIV");
CSP.IV= rsa.Decrypt(Convert.FromBase64String(node.InnerText), true);
步骤2 : 使用得到的KEY与IV解密XML文档:
node=root.SelectNodes("CipherData/CipherValue").Item(0);
byte [] byt = Convert.FromBase64String(node.InnerText);
MemoryStream ms=new MemoryStream(byt);
CryptoStream cs=new CryptoStream
(ms,CSP.CreateDecryptor(CSP.Key,CSP.IV),CryptoStreamMode.Read);
byte[] initialText = new Byte[byt.Length];
//解密文本将其保存为二进制数据
cs.Read(initialText,0,initialText.Length);
六、结语
本文首先根据电子病历结构化的存储结构,提出病历的XML Schema描述,然后探讨了XML电子病历加密与数字签名的方案,并详细说明了其实现步骤。XML作为下一代Web开发的主要技术,在信息交换与存储方面有明显的优势,将其运用到电子病历系统中,可以有效的加强病历的安全性。随着医院信息化的普及,电子病历的加密与签名将十分重要。不过要得到广大患者用户的认可,除技术上的防范措施外,还要在管理上采取严格的控制方法,从而进一步发展以电子病历为核心的医院信息系统。
参考文献
[1]W3C. XML Schema[EB/OL]http://www.w3.org/XML/Schema.
[2]W3C Recommendation.XML Path Language(XPath) [EB/OL]Vl.0.http://www.w3.org/TR/xpath,2003.
[3] Microsoft.net framework[R]. http: //msdn.microsoft.com/netframework/security/,2004.
[4] BoyerJ.Canonical XML Version 1.0[S].RFC 3076,March 2001.
[5]马永恒, 熊前兴, 杨金娥. W3C XML Schema模式的设计方法研究[J]. 计算机应用研究,2006,0.
[6]肖 林. 浅谈电子病历[J]. 档案管理, 2000,04(1).
[7]严维良,于津. XML在电子病历中的应用[J]. 汕头大学学报,2003,15(3).
[8]李浩,孙统风,孟现飞等.基于面向对象思想构建XML Schema[J].微机发展,2003,13(6):59-64.
|