電子商務的快速成長突顯了保護私密資料的重要性,進而提昇對安全演算法的需求。Microsoft® 在 1996 年推出 Cryptography API (Crypto API),率先針對資料的隱私權提出一套解決方案。今日,不斷革新的安全性正是開發加密服務 (例如,Microsoft .NET Common Language Runtime (CLR) 的 System.Security.Cryptography 命名空間) 的主要動力。
此命名空間允許以程式存取各種加密服務。您可以將它們納入應用程式來加密和解密資料,以確保資料完整,並且處理數位簽名和認證。其中一些服務使用於 Framework 的其他地方 (例如 ASP.NET 驗證)。我將概述 .NET Framework 所提供的加密服務基本功能,並提出一些程式碼範例,說明如何在應用程式中使用這些類別。
Cryptography 命名空間
在最高層次,Cryptography 命名空間可分成四個主要區域 (請參閱 [圖 1])。 Cryptography 命名空間的主要功能,是提供執行加密和建立雜湊等演算法時所需的類別。這些演算法是透過可延伸模式來執行。此模式由兩種繼承層次構成。抽象基底類別,如 AsymmetricAlgorithm 或 HashAlgorithm,位於階層頂端,表示演算法類型。第二層抽象類別是衍生自頂層類別,旨在提供演算法的公用介面。例如,SHA1 (安全雜湊演算法) 類別衍生自 HashAlgorithm,並包含 SHA1 演算法專用的方法和屬性。最後,該演算法的實作衍生自第二層,且通常已經過個體化,以供客戶端應用程式使用。在此具體層次,實作可為 Managed、Unmanaged 或兩者並行。
Unmanaged 實作通常包含 CryptoServiceProvider 的字尾,例如,SHA1CryptoServiceProvider,表示此實作實際上是由 Cryptographic Service Provider (CSP) 提供,它安裝在作業系統層次,並在 Crypto API 中作為包裝函式。Managed 實作則包含 Managed 的字尾,例如 SHA1Managed,它不依賴 Crypto API,因此僅在 Managed 程式碼中執行。
關於這些演算法還有另一點值得注意,當其中一個具體類別進行個體化時,如果可能的話,預設建構函式一定在演算法的預設參數中移入合理的安全值。例如,依賴公開金鑰加密的非對稱演算法會產生隨機金鑰組,而對稱演算法同時也會產生隨機金鑰和初始化向量 (IV),並自動設定 Mode 和 Padding 等屬性。甚至,可能的話,演算法將使用 Strong 預設值。
System.Security.Cryptography 命名空間中的第二個主要類別集合,包括在加密和解密資料處理期間實際使用的類別以及各種 Helper 類別。命名空間包含的類別,如抽象 RandomNumberGenerator 類別 (RNGCryptoServiceProvider 即從中衍生),以及在 base 64 之間轉換資料用的 ToBase64Transform 和 FromBase64Transform 類別。
除了加密演算法之外,Cryptography 命名空間亦包含子命名空間 X509Certificates。這包含三個用來代表和管理 Authenticode X.509 v.3 認證的類別。X509Certificate 類別具有 CreateFromCertFile 和 CreateFromSignedFile 靜態方法,以建立認證的執行個體:
Dim c As X509Certificate
c = X509Certificate.CreateFromCertFile("myCert.cer")
Console.WriteLine(c.GetName)
Console.WriteLine(c.GetPublicKeyString)
Console.WriteLine(c.GetSerialNumberString)
Console.WriteLine(c.GetExpirationDateString)
然後認證可用於許多目的,包括透過 System.Net.HttpWebRequest 物件的 ClientCertificates 屬性 (具有 X509CertificateCollection 物件),將認證附加至客戶端要求,以驗證 Web 伺服器。
Cryptography 命名空間也包含子項 XML 命名空間。.NET Framework 安全系統用它來數位簽署 XML 物件。此架構在 XML 簽名語法和處理上遵守 W3C 初稿所訂之規格 (http://www.w3.org/TR/2000/WD-xmldsig-core-20000228/)。此規格包括 XML 語法和處理規則,用來建立和表示數位簽名,並套用至包含此簽名之 XML 文件的任何內部或外部內容。雖然此規格並未涵蓋 XML 的加密 (目前尚無),但它對於提供 XML 文件的整合、訊息驗證、和簽名者驗證服務非常重要。
本文章的其餘內容將集中探討用來套用加密轉換的加密演算法和程式設計模型。
加密演算法
如 [圖 1],Cryptography 命名空間中的其中一種加密演算法是對稱加密演算法。對稱演算法如此命名,是因為它們具有一把可同時用於加密和解密的單一私密金鑰。顯然,寄件者和接收者都必須保護該金鑰的私密性,以確保加密的安全。此外,在 CBC 模式中,對稱演算法需要 IV,這是一個非私密的二進位值,用來初始化演算法和引進其他加密變異數。SymmetricAlgorithm 類別是一個抽象基底類別,它可衍生出其他演算法專用類別。
支援的對稱演算法包括 Data Encryption Standard (DES)、RC2、Rijndael、和 Triple Data Encryption Standard (TripleDES)。每一個演算法都包含一個從 SymmetricAlgorithm 衍生的抽象基底類別,如 DES。它們也包含一個服務提供者類別或已從基底類別衍生的 Managed 類別例如 DESCryptoServiceProvider。此類別包含用來加密和解密資料的方法。關於對稱演算法的階層,請參閱 [圖 2]。
![[圖 2] 對稱演算法](cryptofig02.gif)
[圖 2] 對稱演算法
顯示在 [圖 2] 的具體類別 (如 RijndaelManaged) 可進行個體化,並呼叫其屬性 (請參閱 [圖 3])。在 [圖 3],建立了演算法的新執行個體,它自動產生一個金鑰值和一個 IV 作為位元組陣列,然後序列化成為字串值,並列印至主控台上。請注意,KeySize 和 BlockSize 等屬性可用來判斷金鑰長度,以及在一次作業中可加密或解密多少資料 (位元數)。
第二種類型即所謂的公開金鑰或非對稱演算法;它是從抽象類別 AsymmetricAlgorithm 衍生而來。它們包含知名演算法,例如 Digital Signature Algorithm (DSA) 和 RSA (根據它的建立者 Ron Rivest、Adi Shamir 和 Len Adleman 而命名)。非對稱演算法依賴一組金鑰,一個私密,另一個公開。一般而言,公開金鑰可供任何人使用,寄件者使用它來加密資料,而私密金鑰則必須保持隱密,因為它是用來解密以公開金鑰加密的資料。RSA 通常以此方式來保護資料。
這些演算法都衍生自抽象類別 DSA 和 RSA,而這些抽象類別都衍生自 AsymmetricAlgorithm,如 [圖 4] 所示。不僅如此,演算法的複雜性質表示需要其他 Helper 類別,例如衍生自 AsymmetricKeyExchangeFormatter 和 AsymmetricSignatureFormatter 的類別。
![[圖 4] 非對稱演算法](cryptofig04.gif)
[圖 4] 非對稱演算法
除了允許非對稱演算法的預設建構函式產生金鑰組之外,您還可以從 CSP 所維護的儲存體中擷取現有的金鑰組。若要這麼做,您可以使用 Crypto API 金鑰儲存體中,現有金鑰組的金鑰容器名稱來個體化非對稱演算法,方法是使用金鑰容器名稱移入 CspParameters 物件,並為非對稱演算法的建構函式提供此執行個體。如需如何儲存和擷取非對稱金鑰組的範例,請參閱 http://www.gotdotnet.com/team/clr/about_security.aspx。
Cryptography 命名空間的最後演算法類型是雜湊演算法。此演算法依據較長的位元組序列計算二進值固定大小的唯一序列 (稱為摘要)。您可以使用雜湊演算法來判斷資料是否被擅改。當您隨資料一起傳送摘要時,接收者可以重新計算它。由於若輸入的資料不同,雜湊演算法的輸出便會不同,因此,新舊摘要的比較可指出資料是否已改變。雜湊演算法通常為數位簽名的基礎。
Cryptography 命名空間包含一個叫作 HashAlgorithm 的基底類別,和支援 MD5、SHA1、SHA256、SHA384、和 SHA512 演算法的衍生類別。MD5 演算法產生 128 位元雜湊,SHA1 產生 160 位元雜湊。與 SHA 其他版本相關的數字代表其雜湊的長度。雜湊越大,演算法越安全,越難強制破解。這些演算法包括 Unmanaged 和 Managed 版本,如 [圖 5] 所示。
![[圖 5] 雜湊演算法](cryptofig05.gif)
[圖 5] 雜湊演算法
若要計算摘要,您只需要對雜湊演算法個體化,並呼叫它從 HashAlgorithm 繼承而來的超載 ComputeHash 方法,例如:
Dim fsData As New FileStream("mydata.txt", _
FileMode.Open, FileAccess.Read)
Dim digest() As Byte
Dim oSHA As New SHA512Managed()
digest = oSHA.ComputeHash(fsData)
fsKey.Close()
這裡的 ComputeHash 方法得到一個 Stream 物件,但它也可以接受任何位元組陣列,作為其引數。
Cryptography 命名空間也包含一個叫作 KeyedHashAlgorithm 的抽象類別 (請參閱 [圖 5])。HMACSHA1 和 MACTripleDES 類別中執行的演算法是衍生自 KeyedHashAlgorithm,用以產生 Message Authentication Codes (MAC)。只要寄件者和接收者共用一個私密金鑰,即可使用 MAC 來判斷透過不安全管道傳送的資料是否遭到擅改。
雖然客戶端無法直接個體化 SymmetricAlgorithm、AsymmetricAlgorithm、HashAlgorithm、和 KeyedHashAlgorithm 等抽象基底類別,但可透過它們每一個的超載靜態 (共用) 方法來進行。此方法稱為 Create。在沒有參數情況下,可呼叫此方法來建立特定演算法的執行個體。在預設情況下,這是 RijndaelManaged (對稱)、RSACryptoServiceProvider (非對稱)、SHA1CryptoServiceProvider (雜湊) 和 HMACSHA1 (金鑰型雜湊)。第二個版本亦接受對應至實作的字串 (對應清單位於 .NET Framework 的線上說明中)。與上述方式完全相同,每一個演算法 (例如 SHA) 的抽象類別亦包含一個超載的靜態 Create 方法,以個體化特定演算法的預設實作或接受字串 ID。
不論是哪一種,建立該物件的方法都是透過呼叫 CryptoConfig 類別的 CreateFromName 方法,然後傳送一個字串 ID 給該方法。此對應清單會處理呼叫 Create 方法時所用的預設值。此外,它也會處理傳遞至 Create 方法的字串,對應到特定類別。例如,在沒有參數的情況下呼叫時,Create 方法會將 System.Security.Cryptography.HashAlgorithm 預設字串對應到 SHA1CryptoServiceProvider 類別。在傳遞 SHA1 字串時,該方法會對應到相同類別。
若要說明這些方法,請考慮使用下列程式碼,其中每一個陳述式相當於其他陳述式,並會建立 RijndaelManaged 類別的執行個體:
Dim r, r1, r2, r3 As RijndaelManaged
r3 = CType(CryptoConfig.CreateFromName("Rijndael"), "_
RijndaelManaged)
r2 = CType(SymmetricAlgorithm.Create, RijndaelManaged)
r1 = CType(Rijndael.Create, RijndaelManaged)
r = New RijndaelManaged()
這看起來有點混淆,但以此方式設計類別,是為了要將演算法的挑選,延遲到執行時期或以組態系統指定。事實上,全系統組態檔 (machine.config) 可增加一個 cryptoNameMapping 區段,用來置換預設對應,或新增至以程式寫死在 Mscorlib.dll 中的對應清單。例如,[圖 6] 所顯示的 XML 可新增至 machine.config 檔的組態區段,以將預設雜湊實作設定為 MD5CryptoServiceProvider,並重新對應 dan 字串與實作。
那麼,要如何建立自己的對應呢?您可以在 cryptoClasses 項目內新增一個 cryptoClass 項目以定義要參考的名稱 (在此範例中是指 myMD5),並完整描述該類別和組件。接著使用 nameEntry 項目來建立對應,然後可寫入此客戶端程式碼:
Dim m, m1 As MD5CryptoServiceProvider
m = CType(HashAlgorithm.Create, MD5CryptoServiceProvider)
m1 = CType(CryptoConfig.CreateFromName("dan"), "_
MD5CryptoServiceProvider)
在這兩個執行個體中,都會建立 MD5CryptoServiceProvider 類型的物件。
使用加密服務
以資料流為基礎的程式設計模型在 .NET Framework 中很常見。從 System.IO.Stream 衍生而來的 Stream 類別代表存放區中的資料,如文字檔、XML 文件、MSMQ 訊息、記憶體、和網路,且可交替使用,以便於存放區中進行資料的移入和移出作業。無疑地,Cryptography 命名空間利用此觀念提供理想有效的方式,以使用先前討論過的演算法來加密和解密資料。此功能的核心是 CryptoStream 類別,它衍生自 System.IO.Stream,並作為以資料流為基礎的模型,供加密轉換之用。
為了說明如何在此命名空間使用基本加密功能, [圖 7] 顯示一個簡單的 TextFileCrypto 類別來輔助說明。此類別以對稱方式進行加密和解密檔案,它以該類別產生並存檔的金鑰來使用 DES。
誠如您所見,類別建構函式可個體化具有 CreateEncryptor 和 CreateDecryptor 兩方法的類別層次 DESCryptoServiceProvider 類別。這些方法稍後用來傳回物件以執行加密或解密。公開 KeyFile 和 FileName 屬性是用來開啟一個包含金鑰和 IV 的現有檔案,並設定要加密或解密的檔名。如果金鑰檔已存在,便會使用私密 OpenKeyFile 方法開啟該檔案,並將金鑰和 IV 讀入位元組陣列中。SaveKeyFile 方法呼叫基礎 DES 類別的 GenerateKey 和 GenerateIV 方法來產生一個隨機金鑰和 IV。然後這些值會儲存到以引數傳入的檔案中。此時,金鑰檔應保持私密,並由將使用該金鑰解密資料的人保管。
請注意,DES 演算法使用 56 位元 (7 位元組) 金鑰。雖然 DES 只支援單一金鑰大小,但可透過查詢 LegalKeySizes 屬性來找到其他演算法的有效金鑰大小。這會傳回 KeySize 物件陣列,以 MinSize、MaxSize 和 SkipSize (增量) 等屬性來表示合法大小。例如,Rijndael 演算法支援 128、192 和、256 位元的金鑰大小 。如需更強的加密,可使用 KeySize 屬性設定新大小。
EncryptFile 和 DecryptFile 方法是 TextFileCrypto 類別的核心。EncryptFile 方法所執行的第一個動作是開啟要加密的檔案,以及要儲存加密資料的暫時檔案。然後,它會使用服務提供者 (在此範例中是指 DESCryptoServiceProvider)
的 CreateEncryptor 方法來建立 Encryptor 物件。此物件會執行 ICryptoTransform 介面,因此,可傳遞至 CryptoStream 的建構函式。當資料寫出至 FileStream 所支援的檔案 (在此範例中是指 fsOutput) 時,此建構函式會轉換資料,然後以暫時檔案覆寫原始檔。最後會得到一個加密檔案,且可透過網際網路的 FTP 或以電子郵件附件方式安全地傳送。
DecryptFile 方法則使用 CreateDecryptor 方法建立一個 Decryptor 來執行相反動作。同樣地,此物件會傳至 CryptoStream 的建構函式,來解密從 FileStream fsRead 讀取的檔案。最後,解密資料使用 StreamReader 類別的 ReadToEnd 方法,以 StreamWriter 類別儲存至文字檔。
客戶端可使用 TextFileCrypto 類別,以四行簡單的程式碼加密資料。如下所示:
Dim objCrypt As New TextFileCrypto()
objCrypt.FileName = "students.txt"
' 產生和儲存金鑰
objCrypt.SaveKeyFile("mykey.dat")
' 加密檔案
objCrypt.EncryptFile()
當客戶端接收此檔案時,便可以輕易地解密它:
Dim objCrypt As New TextFileCrypto()
objCrypt.FileName = "students.txt"
' 讀取金鑰
objCrypt.KeyFile = "mykey.dat"
' 解密檔案
objCrypt.DecryptFile()
Windows 中的增強式加密
由於限制增強式加密產品出口的舊法律限制已提高門檻,因此,若您的作業系統是出口版,.NET Framework 不會對 Unmanaged 實作進行增強式加密。若要克服此問題,您可以安裝 High Encryption Pack。Service Pack 2 for Windows 2000 包括了 High Encryption Pack,您可以從 Windows 2000 High Encryption Pack 取得它。
以 Windows NT® 4.0 而言,Service Packs 是以標準和高加密版本配送。如果您尚未安裝,請下載 Service Pack 6a 的高度加密版本。
就 Windows ME、Windows 98 和 Windows 95 而言,Microsoft Internet Explorer 5.5 包括了 High Encryption Pack。如果您執行的 Internet Explorer 版本比 5.5 還要舊,您可以取得對應的 High Encryption Pack。
|