DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> XML 安全: 實現安全層,第 1 部分:基本的保密技術
XML 安全: 實現安全層,第 1 部分:基本的保密技術
編輯:XML詳解     

作為一種 Internet 上的信息交換格式,XML 的普及性仍然在增長——而與信息交換有關的一個重要問題是安全。沒有保證信息的安全性和可靠性的機制,任何信息交換格式都是不完整的。這是 Manish Verma 的系列文章中的第一篇,討論了在保護 XML 中發揮著至關重要作用的技術。本文主要闡述了基本的保密技術、定義了 XML 上下文中的安全性、XML 規范化以及 PKI 基礎設施,並提供了逐步生成密鑰的指南。第 2 部分將討論 XML 加密和 XML 簽名。這一組文章將幫助您實際掌握用於保護 XML 消息的基本技術。

  對於本文的目的而言, 安全性一詞涉及到,從一個客戶機經過數量不定的中間機器到達最終目的地,在這一往復過程中對 XML 的保護。請注意,一個 XML 消息的不同部分可能有不同的最終目的地。保護有效載荷的不同部分,從而使預期的接收群體能夠閱讀它們,而同時又對其他所有中間機器保持加密狀態。

  保護 XML 的基本粒度單位是 元素。加密的粒度還可以進一步細化,規定加密的類型是 元素還是 內容。元素加密對整個元素(包括屬性)加密,並使用 EncryptedData 元素代替它。內容加密基本上意味著只加密元素的子節點,並用 EncryptedData 元素代替。

  安全意味著什麼?

  安全這個術語包含了以下幾個方面:

  機密性保證只有預期的接收者閱讀 XML 中預期的部分。要保證機密性,重要的是加密 XML——XML Encryption 是加密 XML 的標准。

  完整性保證 XML 在從源到最終目的地的傳輸過程中不會被改變。XML Signature 標准允許發送者在要保證完整性的內容後面附加數字簽名。

  真實性是保證 XML 確實是由聲明發送它的人發送的。隨內容一起發送的 XML 簽名可以幫助確保發送者的身份。有效載荷的接收者可以使用發送者的公開密鑰驗證數字簽名。如果數字簽名是有效的,身份就得到了確認,否則就不能確認。

抗否認性用於保證發送者不能否認發送了 XML。由發送者的私鑰生成的附在 XML 上的 XML 簽名保證了發送者的不可駁性。

  XML 規范化是什麼?

  您可以創建看起來不同但擁有相同數據或者相同語義值的 XML 文檔。區別可能在於實體的結構、屬性的排列、字符的編碼或者不起眼的空白。因為存在這種物理差異,任何 XML 文檔都不能進行字節級的等價測試。問題就在於此:數字簽名依賴於字節級的等價測試,但是可能有兩個邏輯上相同但包含不同字節序列的 XML 文檔。

  因此,如果您以數字方式簽署了一些 XML標記,接下來改變了一些屬性的順序——或者增加或去掉一些不重要的空白,但沒有從邏輯上改變 XML,然後再驗證數字簽名的時候的就會失敗。要保證每次驗證邏輯等價的 XML——不管物理表示如何——的數字簽名都能成功,您必須保證 XML 使用公認的標准格式。這個標准稱為 規范化,它是序列化 XML 的標准機制。規范化有兩種形式:

  常規規范化:當序列化 XML 的一部分時,祖先元素的上下文和所有的名稱空間聲明以及 XMLns 名稱空間中的屬性都被包括進來。

  排斥性規范化:當序列化 XML 的一部分時,不包括祖先元素的上下文。

  那麼應該使用哪種規范化,常規規范化還是排斥性規范化呢?考慮這種情況:對於數字簽名,數字簽署的有效載荷可能需要從原來的消息中去掉後插入到不同的上下文中。如果使用常規規范化,載荷將包括原始消息祖先元素的上下文,以及所有的名字空間聲明和 XMLns 名稱空間中的屬性。這樣,從原始消息中提取的數字簽名就不能如實地插入不同的上下文。

  數字簽名需要使用排斥性規范化,因為可以排除祖先元素的上下文、屬性以及 XMLns 名稱空間的聲明,從而使數字簽署的有效載荷可以移植到不同的上下文中。

實現數字簽名的 API 在幕後管理規范化,數字簽署 XML 時您不需要專門考慮規范化的問題。

  我已經充分地討論了規范化,以幫助您了解它的重要性以及如何適應 XML 安全基礎設施的基本框架。下一個話題是 XML 安全基礎設施的另一個重要部分——PKI。

  PKI 基礎

  公共密鑰基礎設施(Public Key Infrastructure,簡寫為 PKI)使得廣大公眾能夠使用像數字簽名和 XML 加密這樣的技術。數字簽名和 XML 加密的核心是 密鑰。密鑰用於數字簽署文檔和驗證簽名,也用於加密和解密過程。PKI 受委托管理與這些密鑰的創建、處理和管理有關的一切事情。

  PKI 保證了以下幾點:

  可靠而有效地管理公鑰和私鑰

  任何時候使用公鑰,您都可以確信關聯的私鑰確實保存在您使用其公鑰的對方手裡

  密鑰是 PKI 中至關重要的部分。這一部分討論不同類型的密鑰,以及如何選擇密鑰的算法。

  公鑰-私鑰組合是公共密鑰基礎設施的核心,建立在非對稱密碼的基礎上。現在我講述如何創建非對稱密鑰,以及如何使用它加密和數字簽署 XML 數據。

  在開始討論公鑰私鑰以及生成它們的基本原理之前,我想首先說明加密和數字簽署 XML 數據的其他方法。

  在加密和數字簽名中,所有的事情都最終歸結為生成密鑰的加密算法。以下是密鑰生成算法所依據的標准:

  算法類型

  算法類型定義加加密算法是對稱的、非對稱的還是消息摘要。這是區分加密算法的根本。

  對稱算法用於生成單個密鑰,也稱為共享密鑰。加密和解密使用相同的密鑰。發起方使用共享密鑰加密或數字簽署有效載荷,接下來,接收方也使用相同的共享密鑰解密或者驗證數字簽名。傳遞共享密鑰可能成為潛在的缺陷:共享密鑰可以通過不同的方式交換,或者共享密鑰本身使用其他密鑰加密。這些共享密鑰交換機制都難以處理。非對稱密鑰解決了這個問題。

盡管對稱密鑰有自身的缺陷(主要是如何在互信的雙方之間傳遞),它們最大的優點是加密解密的速度快。使用共享密鑰加密消息要比使用非對稱密鑰加密快的多。

  非對稱算法 用於生成成對的密鑰。這是 PKI 的基礎。每對密鑰中有一個是公鑰,另一個是私鑰。私鑰(或 應該)只有擁有密鑰對的實體知道。消息的發送方使用接收方的公鑰加密消息。預期的接收者使用相應的私鑰解密消息並閱讀消息。

  與對稱密鑰不同,公鑰可以對一般公眾公開,不必保密。允許公鑰公開的靈活性也帶來了問題,需要一種機制使普通公眾能夠使用它。解決的辦法是 XML 密鑰管理系統(XML Key Management System,簡寫為 XKMS),我將在以後的文章中討論。

  非對稱密鑰的一個缺點是加密消息要比對稱密鑰花費更長的時間,而且加密時間直接與消息的長短成正比。

  使用公鑰和私鑰只加密共享密鑰而不是整個消息可以解決加密時間長的問題。然後再使用共享密鑰加密其他的消息。

  消息摘要是一個安全的、單向的哈希函數,把任意長度的數據轉化成固定長度的校驗和/哈希碼。這些算法用於數字簽名應用程序。要數字簽署大型文件,首先使用這些算法用一種安全的方式壓縮(計算固定長度的哈希碼)文件,然後再用私鑰簽署。

  密鑰長度

  屬於上述算法類型的不同算法使用不同的密鑰長度。這些長度對於不同類型的算法是足夠的,如下所示:

  對於對稱密碼,128 位就足夠了。

  不同的非對稱算法對同樣的位數提供的安全程度是不同的。非對稱密碼中最常說的 RSA 使用 2048 位密鑰,相當於 128 位的對稱密鑰。

  對於消息摘要,算法的長度由算法生成的哈希碼或者校驗和決定。128 位大小的輸出足以保證很高的機密性。使用加密算法的保密性由這樣一個事實保證,即生成與哈希值匹配的明文在計算上是不可行的。

算法的質量

  算法的質量指的是算法 實現的質量。這是由實現對算法規范的忠實性、算法的簡潔性和加密的速度來衡量的。可以根據不同的標准進行不同的測試,以判定哪種實現更好。這是選擇算法要考慮的最低的基本條件。每一類算法的個數都有限,而且新算法出現的很慢。

  如何在 PKI 中使用非對稱算法類型?

  密鑰對的工作原理如下:假定有兩個實體——實體 A 和實體 B。實體 A 已經向實體 B 發送了一條加密的消息。實體 A 取得了實體 B 的公鑰並用它加密消息。因此加密的消息只能使用對應的私鑰解密,而私鑰在實體 B 手中。這就保證了任何人都能使用接收方的公鑰加密消息,但只有接收方(擁有對應的私鑰的一方)能夠解密。

  類似地,數字簽名則是消息發送方使用自己的私鑰簽署消息。接收方可以使用發送方的公鑰驗證數字簽名確認消息的真實性。如果已知的發送方公鑰能夠驗證數字簽名,就認為消息是來自聲明的發送方。

  因此,總結一下 PKI 在 XML 加密和 XML 數字簽名中的使用。

  在 XML 加密中:

  消息的發送方使用接受方的公鑰加密消息並發送。

  消息的接收方使用所擁有的相應的私鑰解密消息。除了擁有對應私鑰的人,其他任何人都不能解密消息,從而保證了它的機密性。

  在 XML 數字簽名中:

  發送方使用自己的私鑰數字簽署要發送的消息。

  接收方使用發送方的對應公鑰驗證數字簽名。

  生成公鑰-私鑰對

  這一部分介紹生成公鑰-私鑰對的過程,這是加密和數字簽名的基礎。

  步驟 1. 基本設置

  您需要為 Java Cryptographic Extension (JCE) 安裝並注冊一個密碼提供程序。JCE 提供程序必須支持生成公鑰和私鑰的 RSA 算法。這是因為與本文配套的示例代碼(請參閱 參考資料)所使用的 XML 加密實現,只支持公私密鑰對的 RSA1_5 算法類型。

在 JDK 1.4 中,SunJCE 提供程序是預先配置好的。這個 SunJCE 提供程序不適合生成非對稱密鑰,因為它沒有包含 RSA 算法類型的實現。附帶的示例代碼使用了開放源代碼的 JCE 提供程序 ISNetworks,它包括了對 RSA 的支持。

  首先,要保證 JCE 提供程序能夠使用。可以通過把提供程序的 .jar 文件放到 CLASSPATH 中實現。

  其次,配置 JCE 提供程序。編輯 JAVA_HOMElibsecurity 目錄下的 Java.security 文件,增加下面一行:

security.provider.n=com.isnetworks.provider.jce.ISNetworksProvider

  動態注冊 JCE 提供程序

  要動態注冊 JCE Provider,可以調用 Java.security.Security 類中的 addProvider 或 insertProviderAt 方法。 addProvider 方法在已經安裝的提供程序列表後面增加新的提供程序,而 insertProviderAt 在指定的位置增加提供程序。如果安裝了安全管理器,可以調用其 checkSecurityAccess 方法看看是否允動態添加新的提供程序。

  Java Runtime Environment (JRE)選擇 JCE 提供程序來載入 JVM。JCE 提供程序的選擇是基於優先順序的。用 n 表示替優先順序,JRE 通過它來挑選 -- 數字越低,優先權越高。

  提供程序的注冊也可以通過代碼動態完成。請參閱 Dynamically registering a JCE provider。

  如果安裝了安全管理器,對於使用 JCE 的 applet 或應用程序必須授權許可。必須為每種提供程序指定許可權限。權限可以在策略文件中指定。

  您可以通過在 "ext" 目錄下作為一組擴展安裝提供程序的 .jar 文件,更清楚地控制這種許可授權事務。

  步驟 2. 生成密鑰對

  清單 1 中的代碼段說明了如何生成密鑰對。

清單 1. 生成密鑰對

KeyPairGenerator pairgen = null;
try {
pairgen = KeyPairGenerator.getInstance("RSA", "ISNetworks");
} catch (NoSuchAlgorithmException e) {
System.out.println("There is no such algorithm for generating the keys");
e.printStackTrace();
} catch (NoSuchProviderException e) {
System.out.println("Not a valid Provider");
e.printStackTrace();
}
SecureRandom random = new SecureRandom();
int KEYSIZE = 1024;
pairgen.initialize(KEYSIZE, random);
KeyPair keyPair = pairgen.generateKeyPair();

  首先,取得一個實現了 RSA 算法的 KeyPairGenerator 對象。

  為 KeyPairGenerator 對象提供密鑰大小和一個隨機數,然後調用 generateKeyPair 方法得到公私密鑰對。一定要掌握好這些密鑰——您將大量使用它們加密和數字簽名。

  生成共享密鑰

  您還需要一個共享密鑰。在 “算法類型” 一節已經提到,共享密鑰用於加密 XML 內容,而公私密鑰對用於加密共享密鑰,內嵌到內容中。

  為了有較好的加密響應時間,而又不采用其他渠道發送共享密鑰,這種戲法是必要的。使用共享密鑰加密 XML 內容可以保證較好的加密響應時間,而密鑰對用於加密共享密鑰本身。

  使用共享密鑰加密非常快。共享密鑰用於加密大量數據,即 XML 的真正內容。使用公司密鑰加密很慢,而且直接與加密的數據大小成正比。因為共享密鑰通常比內容小,公鑰只用於加密共享密鑰,而把共享密鑰本身嵌到內容中。

  本文所附示例代碼中的 XML 加密實現對內容加密只能識別 Triple-DES 算法。清單 2 說明了如何使用 Triple-DES 生成共享密鑰。

  清單 2. 生成共享密鑰

Key ky = null;
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance("DESede", "ISNetworks");
} catch (NoSuchAlgorithmException e) {
System.out.println(
"There is no such algorithm for generating the shared secret");
e.printStackTrace();
} catch (NoSuchProviderException e) {
System.out.println("Not a valid Provider");
e.printStackTrace();
}
ky = kg.generateKey();

  首先,獲得一個實現了 Triple-DES 算法的 KeyGenerator 對象。

  對 KeyGenerator 對象調用 generateKey 方法獲取共享密鑰。這個共享密鑰用於加密 XML 內容。共享密鑰本身使用上一步生成的公鑰加密並嵌入 XML 內容中。

  結束語

  XML 在公共網絡上的數據交換中發揮著卓越的作用。因此,XML 安全標准以及如何采用、解釋和在不同的技術平台上實現這些標准受到了更多的關注。本文中,我客觀地定義了安全性及其基本技術,即 XML 規范化和 PKI 基礎設施,在實現 XML 的安全交換中發揮著重要的作用。在這個基礎上更進一步,本系列的下一篇文章中我將討論 XML 加密和 XML 數字簽名,並提供使用它們的詳細指南。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved