XML Encryption

利用XML Signature, 消息的完整性(Integrity)得到了保證。回顧之前提到的安全的三個基本概念--- Integrity, Confidentiality, Authentication, 現在該考慮消息的機密性的問題,雖然簽名可以保證消息在傳送的途中沒有被篡改,但是並不能避免它被偷取。如果消息沒有經過加密,那麼某個敏感的信息就會被泄漏。與XML Signature類似,結合了XML技術和傳統加密技術而產生的XML Encryption,也並不僅僅是加密XML文件那麼簡單,它提供了以下的功能:
1. 加密整個XML文件。
2. 加密XML文件中的某個元素。
3. 加密XML文件中某個元素的內容。
4. 加密非XML格式的資源。(例如一張JPEG圖片)。
5. 加密已經過加密的內容。

XML Encryption的結構如下所示:
 <EncryptedData (Id)? (Type)? (MimeType)? (Encoding)?>
    (<EncryptionMethod/>)?
    (<ds:KeyInfo>     
       (<ds:KeyName>)?
       (<ds:RetrievalMethod>)?
       (<ds:*>)?
(<EncryptedKey>)?
       (<AgreementMethod>)?
    </ds:KeyInfo>)?
    <CipherData>
      (<CipherValue>)?
      (<CipherReference (URI)?>)?
    </CipherData>
    (<EncryptionProperties>)?
</EncryptedData>
(x)? 代表x出現0-1次  (x)+ 代表x出現1-n次  (x)* 代表x出現0-n次

與XML Signature不同,XML Encryption更加體現了自包含的性質,它不象XML Signature通過引用對某個資源簽名,而是在原資源的位置上創建一個新的EncryptedData元素完全的替代原資源(使用CipherReference除外)。也是因爲這個原因,你不可能象XML Signature那樣在一個Signature元素中對多個資源簽名,有幾個需要加密的資源就有幾個EncryptedData元素替代它們。
     EncryptedData元素是原資源經過XML Encryption作用後的結果,將替代原資源。Type屬性有兩個合法值: element, content. 它們用於區別是否加密tag(標籤)。如果Type設爲element將加密整個元素包括tag在內, 而設爲content時只對元素中的內容加密。
     EncryptionMethod元素指定加密將使用的算法。
     CipherData元素中的內容爲原資源加密後的結果,可以用兩種形式表示,通常使用CipherValue,而CipherReference類似於XML Signature的Reference元素,往往用於對外部資源(jpeg文件)的加密。
     EncryptionProperties元素用於爲加密的數據添加一些額外的信息,比如加密發生的時間。    
     KeyInfo元素描述加密所使用的密鑰。這裏的KeyInfo是借用的XML Signature下的KeyInfo元素。在簽名的時候,大多使用非對稱密鑰,即利用私鑰產生簽名,然後將公鑰信息放在KeyInfo元素中,這樣消息的接受方就可以直接使用公鑰來驗證簽名。但是在加密的時候,通常使用的是對稱密鑰,如果此時把密鑰的信息直接放在KeyInfo中顯然是不安全的。此時有以下幾種方法:
        1. 不使用KeyInfo元素,假定消息交換已經約定好了加密使用的密鑰。
        2. 在KeyInfo中指定一個標識(Identity),假定消息接受方已經擁有了解密所需的密鑰,通過這個標識,消息接受方接可以定位到此次解密所需要的密鑰。
        3. 使用消息接受方的公鑰加密此次加密消息所使用的對稱密鑰,消息接受方利用自己唯一擁有的私鑰解密出加密消息使用的密鑰。
        4. 通過key agreement protocol獲得密鑰(較少使用)。
 
基於以上幾種方法,下面對KeyInfo元素做具體介紹:
    KeyName: 方法2中的一種形式,通過指定一個標識來獲得解密所需的密鑰。
    RetrievalMethod: 方法2中的另一種形式,通過一個URI指向解密所需的密鑰, 比如指向信息中另一段被加密的內容,而那段內容可以方便的被解密。
    EncryptedKey:    爲了使用第三種方法,XML Encryption爲KeyInfo加入的擴展元素。通過非對稱密鑰技術來傳遞對稱密鑰, 綜合了兩種的優點,前提是消息加密方需擁有消息接受方的公鑰。下面是使用該方法的一個例子。
    AgreementMethod: 該元素使用key agreement protocol來獲得密鑰,極少使用故不做介紹。

<EncryptedData>
    <
EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
    <
ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmlsig#" />
        <
EncryptedKey>
            <
EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
            <
ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmlsig#"/>
                <
ds:X509Data>
                    <
ds:X509SubjectName>
                        o=MyCompany,ou=Engineering,cn=Dave Remy
                    </
ds:X509SubjectName>
                </
ds:X509Data>
            </
ds:KeyInfo>
            <
CipherData>
                <
CipherValue>. . .</CipherValue>
            </
CipherData>
        </
EncryptedKey>
    </
ds:KeyInfo>
    <
CipherData>
        <
CipherValue>. . .</CipherValue>
    </
CipherData>
</
EncryptedData>


從上面的例子中可以看出EncryptedKey 和EncryptedData 具有類似的結構,其實它們本來就是同一類型(EncryptedType),一個用於加密數據,一個用於加密密鑰(密鑰就是一種特殊的數據)。它們之間的關係就象面向對象中的sub class和abstract class。EncryptedKey 和EncryptedData是EncryptedType的子類,而EncryptedType是不能具體存在的。因此EncryptedKey可以獨立於EncryptedData存在,甚至EncryptedKey還可以象EncryptedData那樣在子元素中嵌套EncryptedKey或EncryptedData。
瞭解了這個特性,就可以避免在兩段使用相同密鑰加密的消息中重複包含一個複雜的EncryptedKey。利用ReferenceList元素可以在密鑰中引用到使用該密鑰的不同地方,避免重複。

<
Employee>
    <Name>Dave Remy</Name>
    <SocialSecurityNumber>
        <EncryptedData id="socsecnum" Type="http://www.w3.org/2000/09/xmldsig#content">
            <EncryptionMethod Algorithm=". . ." />
            <CipherData>
                 <
CipherValue>. . .</CipherValue>
            </
CipherData>
        </EncryptedData>
    </SocialSecurityNumber>
    <Salary>
        <EncryptedData id="salary" Type="http://www.w3.org/2000/09/xmldsig#content">
            <EncryptionMethod Algorithm=". . .">
            <CipherData><CipherValue>. . .</CipherValue></CipherData>
        </EncryptedData>
    </Salary>
    <EncryptedKey>
        <EncryptionMethod Algorithm=". . ." />
        <CipherData>
            <CipherValue>. . .</CipherValue>
        </CipherData>
        <ReferenceList>
            <DataReference URI="#socsecnum" />
               <DataReference URI="#salary" />
        </ReferenceList>
    </EncryptedKey>
</
Employee>

通過以上方法,可以通過EncryptedKey中的ReferenceList定位到使用該密鑰的不同信息段,但是這是一個單向引用,爲了增加可讀性,以及方便XML Encryption Processor處理還可以通過CarriedKeyName元素來實現雙向引用,在WS-Security中也有類似的實現,示例如下:

<Employee>
    <Name>Dave Remy</Name>
    <SocialSecurityNumber>
        <EncryptedData id="socsecnum" Type="http://www.w3.org/2000/09/xmldsig#content">
            <KeyInfo>
                <KeyName>Jothy Rosenberg</KeyName>
            </KeyInfo>
            <EncryptionMethod Algorithm=". . ." />
            <CipherData>
                 <CipherValue>. . .</CipherValue>
            </CipherData>
        </EncryptedData>
    </SocialSecurityNumber>
    <Salary>
        <EncryptedData id="salary" Type="http://www.w3.org/2000/09/xmldsig#content">
            <EncryptionMethod Algorithm=". . .">
            <CipherData>
                 <CipherValue>. . .</CipherValue>
            </CipherData>
        </EncryptedData>
    </Salary>
    <EncryptedKey>
        <EncryptionMethod Algorithm=". . ." />
        <CipherData>
            <CipherValue>. . .</CipherValue>
        </CipherData>
        <ReferenceList>
            <DataReference URI="#socsecnum" />
            <DataReference URI="#salary" />
        </ReferenceList>
        <CarriedKeyName>Jothy Rosenberg</CarriedKeyName>
    </EncryptedKey>
</
Employee>

與XML Signature相比而言,XML Encryption的創建(加密)和驗證(解密)過程要簡單的多。簡要介紹如下:

加密過程:
1. 選擇一個加密算法
2. 選擇一個加密用的密鑰,如果需要將密鑰的有關信息展示給消息接受方。
3. 在加密前,將待加密的資源轉換爲字符流的格式。
4. 使用選擇的密鑰和算法加密經過串行化的原始消息。
5. 設置加密的類型(Content還是Element?)。
6. 根據結果和以上的選項創建出EncryptedData元素,替代原來的資源。

解密過程:
1. 將CipherValue元素的內容抽取出來。
2. 從EncryptionMethod的Algorithm中獲得加密所用的算法。
3. 獲得加密的類型(Content還是Element?)。
4. 通過KeyInfo中的信息取得密鑰。
5. 根據以上信息將密文解密獲得原始信息。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章