xml的加密和解密
xml加密(XML Encryption)是w3c加密xml的标准。这个加密过程包括加密xml⽂档的元素及其⼦元素,通过加密,xml的初始内容将被替换,但其xml格式仍然被完好的保留。
介绍
我们有3个加密xml的⽅法
1、仅仅使⽤对称加密的⽅法加密xml
这种加密⽅法只使⽤⼀个密钥,也就是说⽆论是加密xml还是解密xml都使⽤⼀个相同的密钥。因为这个密钥不会在被加密的xml中保存,所以我们需要在加密和解密的过程中加载这个密钥并保护它不被窃取。
金贤镇2、使⽤对称加密和⾮对称加密相结合的⽅法来加密xml
这种⽅法需要⼀个⽤于加密数据的对称密钥和⼀个⽤于保护这个对称密钥的⾮对称密钥。被加密的对称密钥和被加密的数据⼀起保存在xml ⽂档中。当⽤私有⾮对称密钥解密密钥的时候要⽤公开⾮对称密钥对密钥进⾏加密。
本⽂就将使⽤这种⽅法。想学到其他更多的⽅法请参看MSDN等到更多的信息。
(译者注:⾮对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是⼀对,如果⽤公开密钥对数据进⾏加密,只有⽤对应的私有密钥才能解密;如果⽤私有密钥对数据进⾏加密,那么只有⽤对应的公开密钥才能解密。因为加密和解密使⽤的是两个不同的密钥,所以这种算法叫作⾮对称加密算法。)
3、使⽤X.509加密xml,这种⽅法是⽤X.509作为⾮对称密钥,它由诸如VeriSign之类的第三⽅提供。
⽅法
不管xml加密是如何完成的,保存加密数据总是⽤两种⽅法之⼀。
1、加密后所有的元素都被命名为<EncryptedData>
2、加密后只有数据被替换,⽽元素名称仍然是可读的,不会发⽣变化。
这种微妙的变化是⾮常重要的。例如:
如果你的xml⽂档中包括被称为<employee>的根元素,该根元素有⼀个下存储了⼀段详细信息的被称做<WrittenWarning>的⼦元素。如果你发送这个xml,并且想<WrittenWarning>这个元素被保护起来,那么使⽤第1中⽅法的话<WrittenWarning>将被替换为<EncryptedData>,你不会从加密后的⽂档中获取到任何可读的信息。
如果使⽤第2种⽅法,那么<WrittenWarning>元素仍然被保留,只⽤数据会被加密。任何得到这个⽂档的⼈虽然不能知道该元素下的详细信息,但仍然知道有⼀些事情发⽣在这个雇员⾝上。另外,<WrittenWarning>元素的所有属性也不会被加密。
所以,如果没有特殊需求,我们⼀般都⽤第1种⽅法。在 2.0中你可以通过修改⼀个Boolean值的属性,便可以⾮常简单的选择使⽤哪种⽅法。
xml加密的例⼦
下⾯这个xml加密的例⼦使⽤的是⾮对称加密法,把xml⽂档的author元素下的内容加密并把author元素⽤<EncryptedData>给替换掉。
xml⽂档
<?xml version="1.0" standalone="no"?>
<article>
<articleinfo>
<title>XPath Queries on XmlDocument objects in .NET 1.1</title>
<abstract>
<para>This article covers the basics.</para>
</abstract>
<author>
<honorific>Mr.</honorific>
<firstname>George</firstname>
<surname>James</surname>
<email>gjames@doman</email>
</author>
</articleinfo>
</article>
XPath表达式为/article/articleinfo/author
被加密后的xml⽂档
<?xml version="1.0" standalone="no"?>
<article>
<articleinfo>
<title>XPath Queries on XmlDocument objects in .NET 1.1</title>
<abstract>
<para>This article covers the basics.</para>
<para>This article does not cover.</para>
</abstract>
<EncryptedData Type="/2001/04/xmlenc#Element"
xmlns="/2001/04/xmlenc#">
<EncryptionMethod            Algorithm="/2001/04/xmlenc#aes256-cbc" />
<KeyInfo xmlns="/2000/09/xmldsig#">
<EncryptedKey xmlns="/2001/04/xmlenc#">
<EncryptionMethod                Algorithm="/2001/04/xmlenc#rsa-1_5" />
<KeyInfo xmlns="/2000/09/xmldsig#">
<KeyName>session</KeyName>
</KeyInfo>
<CipherData>
<CipherValue>r4f7SI1aZKSvibb…</CipherValue>
</CipherData>
</EncryptedKey>
</KeyInfo>
<CipherData>
童星阿尔法近况曝光<CipherValue>sGNhKqcSovipJdOFCFKYEEMRFd…</CipherValue>
走光露毛</CipherData>
</EncryptedData>
</articleinfo>
</article>
author元素及其⼦元素都将被<EncryptedData>给替换掉,另外还包括其他⼀些元素,如加密算法,密钥等。
<EncryptedData>元素
仔细看看<EncryptedData>元素的树形结构,你会发现<EncryptedData>元素下分解出了很多⼦元素。其中<KeyInfo>元素与xml数字签名中的<KeyInfo>元素是相同的。
EncryptedData元素被包含在“/2001/04/xmlenc#”命名空间中。它是被加密数据的根元素。
EncryptionMethod元素指定加密数据的对称⽅法。做这件事需要使⽤⼀个包含了w3 url的算法属性 -
“/2001/04/xmlenc#aes256-cbc”,它指出数据是⽤AES(Rijndael)以256k的密钥加密的。
KeyInfo元素来⾃xml数字签名,它保存着对称密钥的信息,除此之外该元素还能保存更多的信息。
KeyInfo元素下的EncryptedKey元素及其⼦元素包含着关于被保存的密钥的信息。
KeyInfo下的EncryptionMethod元素包含的⾮对称加密⽅法⽤来加密对称密钥。做这件事需要把⼀个算法属性设置给w3 url。例
如:“/2001/04/xmlenc#rsa-1_5”说明使⽤了RSA⾮对称算法来加密对称密钥。
KeyName元素是⼀个标识符,⽤来发现密钥。稍后在我们编程的时候你将会发现它的重要性。
CipherData元素和CipherValue元素出现在EncryptedKey元素和EncryptedData元素下,它们包含着密码数据。事实上密码数据保存在CipherValue元素下的。EncryptedKey元素下保存的是被加密的密钥,EncryptedData元素下的CipherValue保存的是被加密的数据。
⾮对称xml加密步骤
xml加密的过程可以概括为以下五步:
1、选择xml⽂档中的⼀个元素(选择根元素的话将加密整个⽂档)
2、使⽤⼀个对称密钥加密元素
3、使⽤⾮对称加密来加密上⾯那个对称密钥(使⽤公开密钥)
4、创建⼀个EncryptedData元素,该元素下将包含被加密的数据和被加密的密钥
5、⽤加密后的元素替换掉初始元素。
这些步骤的⼤部分都可以使⽤ 2.0中的类⾃动完成。
⾮对称xml解密步骤
xml解密的过程可以概括为以下四步:
1、在xml⽂档中选择⼀个EncryptedData元素
2、使⽤⼀个⾮对称密钥来解密密钥(使⽤私有密钥)
3、使⽤未加密的密钥来解密数据
4、把EncryptedData元素替换成未加密的元素
这些步骤的⼤部分都可以使⽤ 2.0中的类⾃动完成。
命名空间
完成xml的加密,我们需要引⼊三个命名空间
System.Xml - 包含操作xml的类
System.Security.Cryptography - 包含⽣成加密密钥的类
System.Security.Cryptography.Xml - 包含完成加密任务的类
使⽤加密xml
本⽂提供了⼀个简单的加密、解密xml的应⽤程序,下⾯我们⼀起来看⼀看相关的代码。这个⽰例只有⼀些基本功能,你可以再额外加⼀些如选择节点之类的功能
⾸先加载⾮对称公开密钥来加密密钥
// 创建⼀个⽤于加密密钥的⾮对称密钥
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// 加载⼀个公开密钥
XmlDocument pubKeys = new XmlDocument();
pubKeys.Load(Application.StartupPath + "\\xml.dev.keys.public");
// 使⽤公开密钥加密密钥
rsa.FromXmlString(pubKeys.OuterXml);
接下来加载xml⽂档并选择⼀个需要加密的节点。下⾯的代码⽰例了如何使⽤⼀个XPath表达式来选择节点。如果不选择节点,则整个xml⽂档都将被加密。
// xml⽂档
// 给xml⽂档加载⼀些节点和数据(省略)
XmlElement encElement;
巴基斯坦外交部长
// 如果没有xpath则
if (xpath == string.Empty)
杨奇函{
encElement = lEncDoc.DocumentElement;
秦丽个人资料
}
else
{
XmlNamespaceManager xmlns = lnsManager;
// 通过xpath选择出需要加密的元素
encElement = lEncDoc.SelectSingleNode(xpath, xmlns) as XmlElement;
}
使⽤EncryptedXml类去加密数据和密钥
// 完成加密xml的类
EncryptedXml xmlEnc = new lEncDoc);
// 增加⼀个“session”密钥,使⽤rsa编码
xmlEnc.AddKeyNameMapping("session", rsa);
// 使⽤“session”密钥来加密数据
// 这些信息被保存在KeyInfo元素下
EncryptedData encData = xmlEnc.Encrypt(encElement, "session");
⽤加密后的元素替换初始元素
// ⽤加密后的元素替换初始元素
EncryptedXml.ReplaceElement(encElement, encData, false);
使⽤解密xml
⾸先加载私有⾮对称密钥来解密密钥
// 创建⼀个⽤于解密密钥的⾮对称密钥
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// 加载私有密钥
XmlDocument privKeys = new XmlDocument();
privKeys.Load(Application.StartupPath + "\\xml.dev.keys.private");
// 使⽤私有密钥来解密密钥
rsa.FromXmlString(privKeys.OuterXml);
增加⼀个密钥名称并映射到被加密的⽂档中
// 增加⼀个密钥名称并映射到被加密的⽂档中
EncryptedXml encXml = new EncryptedXml(xmlEncDoc);
encXml.AddKeyNameMapping("session", rsa);
通过指定的密钥来解密⽂档的每⼀个EncryptedData元素
// 解密所有<EncryptedData>元素
encXml.DecryptDocument();
总结
xml加密(XML Encryption)是w3c加密xml的标准。加密后的⽂档仍然是xml格式。我们使⽤⾮对称和对称算法来加密xml,对称算法⽤于加密数据,⾮对称算法⽤于加密对称算法中的密钥,加密后的数据被保存在EncryptedData元素下。EncryptedData元素包含着⼀些列⽤于描述算法的⼦元素,同时也包含着密钥信息。
参考
下载
译者补充:
2.0下加密和解密fig⽂件中的某个section
aspnet_regiis –pef appSettings C:\Inetpub\wwwroot\website
aspnet_regiis –pdf appSettings C:\Inetpub\wwwroot\website