介紹
我們有3個(gè)加密xml的方法
1、僅僅使用對(duì)稱(chēng)加密的方法加密xml
這種加密方法只使用一個(gè)密鑰,也就是說(shuō)無(wú)論是加密xml還是解密xml都使用一個(gè)相同的密鑰。因?yàn)檫@個(gè)密鑰不會(huì)在被加密的xml中保存,所以我們需要在加密和解密的過(guò)程中加載這個(gè)密鑰并保護(hù)它不被竊取。
2、使用對(duì)稱(chēng)加密和非對(duì)稱(chēng)加密相結(jié)合的方法來(lái)加密xml
這種方法需要一個(gè)用于加密數(shù)據(jù)的對(duì)稱(chēng)密鑰和一個(gè)用于保護(hù)這個(gè)對(duì)稱(chēng)密鑰的非對(duì)稱(chēng)密鑰。被加密的對(duì)稱(chēng)密鑰和被加密的數(shù)據(jù)一起保存在xml文檔中。當(dāng)用私有非對(duì)稱(chēng)密鑰解密密鑰的時(shí)候要用公開(kāi)非對(duì)稱(chēng)密鑰對(duì)密鑰進(jìn)行加密。
本文就將使用這種方法。想學(xué)到其他更多的方法請(qǐng)參看MSDN等到更多的信息。
(譯者注:非對(duì)稱(chēng)加密算法需要兩個(gè)密鑰:公開(kāi)密鑰(publickey)和私有密鑰(privatekey)。公開(kāi)密鑰與私有密鑰是一對(duì),如果用公開(kāi)密鑰對(duì)數(shù)據(jù)進(jìn)行加密,只有用對(duì)應(yīng)的私有密鑰才能解密;如果用私有密鑰對(duì)數(shù)據(jù)進(jìn)行加密,那么只有用對(duì)應(yīng)的公開(kāi)密鑰才能解密。因?yàn)榧用芎徒饷苁褂玫氖莾蓚€(gè)不同的密鑰,所以這種算法叫作非對(duì)稱(chēng)加密算法。)
3、使用X.509加密xml,這種方法是用X.509作為非對(duì)稱(chēng)密鑰,它由諸如VeriSign之類(lèi)的第三方提供。
方法
不管xml加密是如何完成的,保存加密數(shù)據(jù)總是用兩種方法之一。
1、加密后所有的元素都被命名為<EncryptedData>
2、加密后只有數(shù)據(jù)被替換,而元素名稱(chēng)仍然是可讀的,不會(huì)發(fā)生變化。
這種微妙的變化是非常重要的。例如:
如果你的xml文檔中包括被稱(chēng)為<employee>的根元素,該根元素有一個(gè)下存儲(chǔ)了一段詳細(xì)信息的被稱(chēng)做<WrittenWarning>的子元素。如果你發(fā)送這個(gè)xml,并且想<WrittenWarning>這個(gè)元素被保護(hù)起來(lái),那么使用第1中方法的話<WrittenWarning>將被替換為<EncryptedData>,你不會(huì)從加密后的文檔中獲取到任何可讀的信息。
如果使用第2種方法,那么<WrittenWarning>元素仍然被保留,只用數(shù)據(jù)會(huì)被加密。任何得到這個(gè)文檔的人雖然不能知道該元素下的詳細(xì)信息,但仍然知道有一些事情發(fā)生在這個(gè)雇員身上。另外,<WrittenWarning>元素的所有屬性也不會(huì)被加密。
所以,如果沒(méi)有特殊需求,我們一般都用第1種方法。在.net 2.0中你可以通過(guò)修改一個(gè)Boolean值的屬性,便可以非常簡(jiǎn)單的選擇使用哪種方法。
xml加密的例子
下面這個(gè)xml加密的例子使用的是非對(duì)稱(chēng)加密法,把xml文檔的author元素下的內(nèi)容加密并把a(bǔ)uthor元素用<EncryptedData>給替換掉。
XML文檔:
<?xml version="1.0" standalone="no"?> |
XPath表達(dá)式為/article/articleinfo/author
被加密后的xml文檔:
<?xml version="1.0" standalone="no"?> |
author元素及其子元素都將被<EncryptedData>給替換掉,另外還包括其他一些元素,如加密算法,密鑰等。
<EncryptedData>元素
仔細(xì)看看<EncryptedData>元素的樹(shù)形結(jié)構(gòu),你會(huì)發(fā)現(xiàn)<EncryptedData>元素下分解出了很多子元素。其中<KeyInfo>元素與xml數(shù)字簽名中的<KeyInfo>元素是相同的。
EncryptedData元素被包含在“http://www.w3.org/2001/04/xmlenc#”命名空間中。它是被加密數(shù)據(jù)的根元素。
EncryptionMethod元素指定加密數(shù)據(jù)的對(duì)稱(chēng)方法。做這件事需要使用一個(gè)包含了w3 url的算法屬性 - “http://www.w3.org/2001/04/xmlenc#aes256-cbc”,它指出數(shù)據(jù)是用AES(Rijndael)以256k的密鑰加密的。
KeyInfo元素來(lái)自xml數(shù)字簽名,它保存著對(duì)稱(chēng)密鑰的信息,除此之外該元素還能保存更多的信息。
KeyInfo元素下的EncryptedKey元素及其子元素包含著關(guān)于被保存的密鑰的信息。
KeyInfo下的EncryptionMethod元素包含的非對(duì)稱(chēng)加密方法用來(lái)加密對(duì)稱(chēng)密鑰。做這件事需要把一個(gè)算法屬性設(shè)置給w3 url。例如:“http://www.w3.org/2001/04/xmlenc#rsa-1_5”說(shuō)明使用了RSA非對(duì)稱(chēng)算法來(lái)加密對(duì)稱(chēng)密鑰。
KeyName元素是一個(gè)標(biāo)識(shí)符,用來(lái)發(fā)現(xiàn)密鑰。稍后在我們編程的時(shí)候你將會(huì)發(fā)現(xiàn)它的重要性。
CipherData元素和CipherValue元素出現(xiàn)在EncryptedKey元素和EncryptedData元素下,它們包含著密碼數(shù)據(jù)。事實(shí)上密碼數(shù)據(jù)保存在CipherValue元素下的。EncryptedKey元素下保存的是被加密的密鑰,EncryptedData元素下的CipherValue保存的是被加密的數(shù)據(jù)。
非對(duì)稱(chēng)xml加密步驟
xml加密的過(guò)程可以概括為以下五步:
1、選擇xml文檔中的一個(gè)元素(選擇根元素的話將加密整個(gè)文檔)
2、使用一個(gè)對(duì)稱(chēng)密鑰加密元素
3、使用非對(duì)稱(chēng)加密來(lái)加密上面那個(gè)對(duì)稱(chēng)密鑰(使用公開(kāi)密鑰)
4、創(chuàng)建一個(gè)EncryptedData元素,該元素下將包含被加密的數(shù)據(jù)和被加密的密鑰
5、用加密后的元素替換掉初始元素。
這些步驟的大部分都可以使用.net 2.0中的類(lèi)自動(dòng)完成。
非對(duì)稱(chēng)xml解密步驟
xml解密的過(guò)程可以概括為以下四步:
1、在xml文檔中選擇一個(gè)EncryptedData元素
2、使用一個(gè)非對(duì)稱(chēng)密鑰來(lái)解密密鑰(使用私有密鑰)
3、使用未加密的密鑰來(lái)解密數(shù)據(jù)
4、把EncryptedData元素替換成未加密的元素
這些步驟的大部分都可以使用.net 2.0中的類(lèi)自動(dòng)完成。
命名空間
完成xml的加密,我們需要引入三個(gè)命名空間
System.Xml - 包含操作xml的類(lèi)
System.Security.Cryptography - 包含生成加密密鑰的類(lèi)
System.Security.Cryptography.Xml - 包含完成加密任務(wù)的類(lèi)
使用.net加密xml
本文提供了一個(gè)簡(jiǎn)單的加密、解密xml的應(yīng)用程序,下面我們一起來(lái)看一看相關(guān)的代碼。這個(gè)示例只有一些基本功能,你可以再額外加一些如選擇節(jié)點(diǎn)之類(lèi)的功能
首先加載非對(duì)稱(chēng)公開(kāi)密鑰來(lái)加密密鑰
// 創(chuàng)建一個(gè)用于加密密鑰的非對(duì)稱(chēng)密鑰 |
接下來(lái)加載xml文檔并選擇一個(gè)需要加密的節(jié)點(diǎn)。下面的代碼示例了如何使用一個(gè)XPath表達(dá)式來(lái)選擇節(jié)點(diǎn)。如果不選擇節(jié)點(diǎn),則整個(gè)xml文檔都將被加密。
// xml文檔 |
使用EncryptedXml類(lèi)去加密數(shù)據(jù)和密鑰
// 完成加密xml的類(lèi) |
用加密后的元素替換初始元素
// 用加密后的元素替換初始元素 |
使用.net解密xml
首先加載私有非對(duì)稱(chēng)密鑰來(lái)解密密鑰
// 創(chuàng)建一個(gè)用于解密密鑰的非對(duì)稱(chēng)密鑰 |
總結(jié)
xml加密(XML Encryption)是w3c加密xml的標(biāo)準(zhǔn)。加密后的文檔仍然是xml格式。我們使用非對(duì)稱(chēng)和對(duì)稱(chēng)算法來(lái)加密xml,對(duì)稱(chēng)算法用于加密數(shù)據(jù),非對(duì)稱(chēng)算法用于加密對(duì)稱(chēng)算法中的密鑰,加密后的數(shù)據(jù)被保存在EncryptedData元素下。EncryptedData元素包含著一些列用于描述算法的子元素,同時(shí)也包含著密鑰信息。