密碼編譯服務
像網際網路的公用網路並不提供實體 (Entity) 間安全的通訊方式。 這類網路上的通訊很容易就被未授權的第三者讀取或甚至修改。 密碼編譯有助於使資料不被檢視,而且會提供方式來偵測資料是否已遭修改,同時可協助在其他不安全的通道上提供安全的通訊方式。 例如,資料可使用密碼編譯演算法加密以及在加密的狀態下傳送,並在稍後由指定的一方進行解密。 即使第三者攔截到這些加密資料也很難破解。
在 .NET Framework 中,System.Security.Cryptography 命名空間中的類別會為您管理許多加密的詳細資訊。 某些是 Unmanaged Microsoft Cryptography API (CryptoAPI) 的包裝函式,其他則僅是 Managed 實作。 您不需要是加密方面的專家,就可以使用這些類別。 當您建立任何一個加密演算法類別的新執行個體時,金鑰就會自動產生以方便使用,而且預設屬性也會盡可能的安全可靠。
這份概觀會概要介紹 .NET Framework 所支援的加密方法和實務作法,其中包括 .NET Framework 3.5 版所提供的 ClickOnce 資訊清單、Suite B 和 Cryptography Next Generation (CNG) 支援。
本概觀包含下列各節:
基本密碼編譯
私密金鑰加密
公開金鑰加密
數位簽章
雜湊值
亂數產生
ClickOnce 資訊清單
Suite B 支援
Cryptography Next Generation (CNG) 類別
相關主題
如需與密碼編譯相關,以及可讓您為應用程式加入密碼編譯安全性之 Microsoft 服務、元件和工具的詳細資訊,請參閱本文件的「Win32 和 COM 程式開發」、「安全性」等章節的內容。
基本密碼編譯
通常使用密碼編譯的情況為:兩方 (Alice 和 Bob) 在不安全的通道上進行通訊。 Alice 和 Bob 希望確保他們的通訊不會被任何正在接聽的人所了解。 甚至,由於 Alice 和 Bob 位置距離遙遠,Alice 必須確定她從 Bob 收到的資訊,在傳輸時未經任何修改。 此外,她還必須要確定這些資訊的確是來自 Bob 而不是某個假冒 Bob 的人傳送來的。
可使用密碼編譯達到以下目的:
機密性:利於避免使用者的身分或資料被讀取
資料完整性:利於避免資料被變更。
驗證:確保資料是來自特定的一方。
不可否認性:防止特定的一方否認自己是訊息傳送者。
若要達成這些目標,您可以使用稱為基本密碼編譯的演算法與實施方針組合,來建立密碼編譯配置。 下表列出基本密碼編譯和其用法。
基本密碼編譯 |
用法 |
---|---|
私密金鑰加密 (對稱密碼編譯) |
執行資料轉換,避免資料被第三方讀取。 這類型的加密使用單一公開、機密的金鑰來加密及解密資料。 |
公開金鑰加密 (非對稱密碼編譯) |
執行資料轉換,避免資料被第三方讀取。 這類型的加密使用公開/私密金鑰組 (Key Pair) 來加密及解密資料。 |
密碼編譯簽章 |
藉由建立唯一的數位簽章,協助驗證資料是來自特定的一方。 這項處理也使用雜湊函式。 |
密碼編譯雜湊 |
將任意長度的資料對應到固定長度位元組序列 (Sequence)。 雜湊在統計學上是獨一無二的;不同的二位元組序列將不會雜湊出相同的值。 |
回到頁首
私密金鑰加密
私密金鑰加密演算法使用單一私密金鑰來加密和解密資料。 您必須要設定金鑰的安全性,避免未授權的中間人存取,因為只要有金鑰就可以用它來將您的資料解,或宣稱資料是由您所送出而進行加密自己的資料。
私密金鑰加密也稱為對稱加密,因為相同的金鑰可用來加密和解密。 私密金鑰加密演算法的速度非常快 (相較於公開金鑰演算法),並且十分適合執行大資料流的密碼編譯轉換。 非對稱加密演算法 (如 RSA) 在數學上會受限於所能加密的資料量。 對稱式加密演算法通常不會出現這類問題。
稱為區塊密碼器 (Cipher) 的私密金鑰演算法類型,會用於進行一次加密一個資料區塊。 包括像是資料加密標準 (Data Encryption Standard,DES)、TripleDES、先進加密標準 (Advanced Encryption Standard,AES) 的區塊密碼器,會以密碼編譯方式將 n 位元組的輸入區塊轉換為加密位元組的輸出區塊。 如果您希望將位元組序列加密或解密,您必須分區塊執行。 因為 n 很小 (DES 和 TripleDES 為 8 個位元組;AES 則為 16 個位元組 [預設值]、24 個位元組或 32 個位元組),所以大於 n 的資料值必須一次加密一個區塊。 小於 n 的資料值必須擴展為 n 才能繼續進行。
有一種稱為電子密碼書 (Electronic Codebook,ECB) 模式的簡單形式區塊密碼器。 ECB 模式並不被視為安全,因為它不會使用初始化向量 (Initialization Vector) 來初始化第一個純文字區塊。 對於已知的私密金鑰 k,不使用初始化向量的簡單區塊密碼,會將同一個純文字輸入區塊加密成同一個密碼文字輸出區塊。 因此,如果您輸入的純文字資料流中有重複的區塊,您的輸出密碼文字資料流中就會有重複的區塊。 這些重複的輸出區塊會發出警示,表示弱式加密演算法的未經授權使用者使用了可能已採用的演算法,以及可能的攻擊模式。 因此,ECB 加密模式很容易進行分析,並在最後進行金鑰探索。
由基底類別程式庫提供的區塊密碼器類別會使用稱為密碼區塊鏈結 (Cipher-Block Chaining,CBC) 的預設鏈結模式,不過您可以視需要變更此預設值。
CBC 加密會藉由使用初始化向量 (IV) 來加密第一個純文字區塊,解決與 ECB 加密有關的問題。 後續的每個純文字區塊都會在其進行加密之前,與前一個密碼文字區塊執行位元排除 OR (XOR) 運算。 因此,每個密碼文字區塊都會相依於所有的先前區塊。 使用這套系統時,就不能使用未授權使用者可能知道的通用訊息頁首來進行金鑰的還原工程。
另一種會洩露利用 CBC 加密所加密之資料的方法,是大規模搜尋每個可能的金鑰。 即使是使用最快速的電腦,進行這種搜尋仍非常耗時,而所耗費的時間依照執行加密的金鑰大小而定,因此是不可行的。 較大的金鑰大小就較難破解。 雖然理論上加密無法完全避免駭客擷取加密資料,但是加密確實會提高駭客進行擷取時所花費的成本。 如果花三個月的時間執行大規模的搜尋,只擷取到數天有用的資料,這樣的大規模搜尋是不切實際的。
私密金鑰加密的缺點是,它是假設通訊的兩方已同意某個金鑰和 IV,而且已經相互交換過值。 IV 並不被視為機密,因此可以與訊息一起以純文字傳送。 不過,這個金鑰必須避免被未經授權的使用者知曉。 基於這些問題,私密金鑰加密通常會結合公開金鑰加密,以便隱密傳送金鑰和 IV 的值。
假設 Alice 和 Bob 是要在不安全通道上通訊的雙方人員,他們可以依下面所述方式來使用秘密金鑰加密:Alice 和 Bob 都同意搭配特定金鑰和 IV 來使用特定演算法 (例如 AES)。 Alice 撰寫好訊息並建立網路資料流 (或許是具名管道或網路電子郵件),並在資料流上傳送這個訊息。 接著,她使用金鑰和 IV 來加密文字,並透過網際網路傳送加密訊息和 IV 給 Bob。 Bob 收到加密文字,並使用 IV 和先前雙方同意的金鑰解密。 即使傳送的訊息被攔截,由於攔截者不知道金鑰,所以也不可能復原原始訊息。 在這個案例中,只有金鑰必須保持秘密。 在真實世界的案例中,不論是 Alice 或 Bob 產生了私密金鑰,都會使用公開金鑰 (非對稱) 加密將私密 (對稱) 金鑰傳給對方。 如需公開金鑰加密的詳細資訊,請參閱下一節的內容。
.NET Framework 會提供下面可實作私密金鑰加密演算法的類別:
AesManaged (在 .NET Framework 3.5 版中加入)
HMACSHA1 (從技術上來說,這是一種私密金鑰演算法,因為它代表使用結合私密金鑰之密碼編譯雜湊函式進行計算所得的訊息驗證碼 請參閱本主題稍後雜湊值一節的內容)
回到頁首
公開金鑰加密
公開金鑰加密使用到必須避免未授權使用者知道的私密金鑰,同時使用可公開讓所有人知道的公開金鑰。 從數學的角度來看,公開金鑰和私密金鑰是連結在一起的;利用公開金鑰加密的資料,只能利用私密金鑰解密,而利用私密金鑰簽章的資料,只能利用公開金鑰驗證。 公開金鑰可提供給任何人;這個金鑰是用來加密要傳送給私密金鑰保管人的資料。 公開金鑰密碼編譯演算法也就是所謂的非對稱演算法,因為一個金鑰需要用來加密資料,而另一個金鑰用來解密資料。 基本的密碼編譯規則會禁止重複使用金鑰,對於每個通訊工作階段而言,這兩個金鑰應該都是唯一的。 然而實務上,非對稱金鑰的存留期通常會比較長。
雙方 (Alice 和 Bob) 可以依照下述步驟使用公開金鑰加密:首先,Alice 產生公開/私密金鑰組。 如果 Bob 要將加密過的訊息傳送給 Alice,他要先向她取得她的公開金鑰。 Alice 在不安全的網路上將她的公開金鑰傳送給 Bob,Bob 利用這個金鑰加密訊息 Bob 將加密過的訊息傳送給 Alice,而且她會使用自己的私密金鑰來解密。 如果 Bob 是在不安全通道上接收到 Alice 的金鑰 (例如公用網路上),這時 Bob 可能會遭受到攔截式攻擊。 因此,Bob 必須要向 Alice 驗證他已拿到正確的公開金鑰。
在 Alice 傳輸公開金鑰期間,可能會有未經授權的中間人攔截到這個金鑰。 甚至,相同的中間人可能攔截到 Bob 傳送出來的加密訊息。 但是,這個中間人無法利用公開金鑰將訊息解密。 訊息只能利用 Alice 的私密金鑰解密,但這個金鑰未被傳送過。 Alice 不會使用她的私密金鑰來加密給 Bob 的回信,因為任何人只要有了公開金鑰都可以將訊息解密。 如果 Alice 要將訊息傳回給 Bob,她會向 Bob 取得他的公開金鑰,使用公開金鑰來加密她的訊息。 然後 Bob 會使用他的私密金鑰來解密訊息。
在此案例中,Alice 和 Bob 使用公開金鑰 (非對稱) 加密來傳送私密 (對稱) 金鑰,並在其他工作階段都使用私密金鑰加密。
下列清單提供您公開金鑰和秘密金鑰密碼編譯演算法之間的比較:
公開金鑰密碼編譯演算法使用固定的緩衝區大小,而私密金鑰密碼編譯演算法則使用可變長度的緩衝區。
公開金鑰演算法無法像私密金鑰演算法所作的一樣,用來將資料鏈結在一起成為資料流,因為只有小量的資料可加密。 因此,非對稱作業和對稱作業所使用的資料流模型不相同。
公開金鑰加密的金鑰空間 (金鑰可能值的範圍),比秘密金鑰加密大很多。 因此,公開金鑰加密比較不容易被想要嘗試所有可能金鑰的周延攻擊者破解。
因為公開金鑰不需要特別保護,因此容易進行散發,條件是要有方法可以驗證傳送者的識別身分。
某些公開金鑰演算法 (如 RSA 和 DSA,但不包括 Diffie-Hellman) 可用來建立可驗證資料寄件人識別身分的數位簽章。
公開金鑰演算法的速度比秘密金鑰演算法慢很多,因此不會設計用來加密大量的資料。 公開金鑰演算法只適合傳送非常小量的資料。 通常,公開金鑰加密用來加密私密金鑰演算法所使用的金鑰和 IV。 在傳送過金鑰和 IV 後,剩餘的工作階段就使用私密金鑰加密。
.NET Framework 會提供下面可實作公開金鑰加密演算法的類別:
ECDiffieHellman (基底類別)
ECDiffieHellmanCngPublicKey (基底類別)
RSA 可讓您進行加密和簽署,而 DSA 只能用於簽署,Diffie-Hellman 則只能夠用於產生金鑰。 一般而言,公開金鑰演算法在使用上會比私密金鑰演算法受到更多限制。
回到頁首
數位簽章
公開金鑰演算法也可用來構成數位簽章。 數位簽章驗證寄件人的身分 (如果您信任寄件人的公開金鑰) 並協助保護資料的完整性。 使用 Alice 所產生的公開金鑰,Alice 資料的收件者可藉由比對數位簽章以及 Alice 的資料和 Alice 的公開金鑰,來驗證的確是 Alice 傳送出來的訊息。
若要使用公開金鑰加密以數位方式為訊息簽章,Alice 首先要將雜湊演算法套用到訊息,以建立訊息摘要。 這個訊息摘要是資料的壓縮和唯一表示方式。 接著 Alice 利用她的私密金鑰加密訊息摘要,建立起她個人的簽章。 在收到這個訊息和簽章時,Bob 會使用 Alice 的公開金鑰解密這個簽章以復原訊息摘要,並且使用 Alice 所使用的相同雜湊演算法雜湊這個訊息。 如果 Bob 計算出來的訊息摘要完全符合從 Alice 接收到的訊息摘要,Bob 就可以確信訊息是來自私密金鑰的擁有人,且資料未被修改。 如果 Bob 信任 Alice 是私密金鑰的擁有人,他就會知道訊息是來自 Alice。
注意事項 |
---|
簽章可由任何人來加以驗證,因為寄件人的公開金鑰是通用資訊,而且通常包含在數位簽章格式中。這種方法並不能保持訊息的機密性;對於要保密的訊息,還必須要進行加密。 |
.NET Framework 會提供下面可實作數位簽章演算法的類別:
回到頁首
雜湊值
雜湊演算法將任意長度的二進位值對應到固定長度較小的二進位值,稱為雜湊值 (Hash Value)。 雜湊值是資料片段的數值表示方式。 如果您雜湊演算一段純文字,然後即使只變更這個段落中的一個字母,接下來的雜湊演算就會產生不一樣的值。 如果雜湊演算在密碼編譯方式上屬於強式,則其值會有大幅度的變動。 例如,如果訊息的單一位元已變更,則強式雜湊函式可能會產生具有 50% 差異的輸出。 許多輸入值可能會雜湊演算出相同的輸出值。 不過就計算上而言,不可能找到兩個不同的輸入能雜湊演算出相同值的情形。
雙方 (Alice 和 Bob) 可以使用雜湊函式來確保訊息完整性。 他們要選取雜湊演算法來簽署訊息。 Alice 會撰寫訊息,然後再藉由使用選取的演算法建立該訊息的雜湊。 接著他們要遵循下列其中一個方法:
Alice 傳送純文字訊息和雜湊訊息 (數位簽章) 給 Bob。 Bob 接收並雜湊該訊息,並將他的雜湊值與他從 Alice 處接收到的雜湊值進行比較。 如果兩個雜湊值完全相同,表示這個訊息未被變更。 但如果兩個值不相同,就表示這個訊息在 Alice 撰寫後有被變更過。
可惜的是,這個方法並不會建立傳送者的真實性檢查。 所以任何人都可以模擬為 Alice 並傳送訊息給 Bob。 他們可以使用相同的雜湊演算法簽署訊息,而 Bob 能做的所有判斷就是訊息跟其簽章是否相符。 這是一種型式的攔截式攻擊。 如需詳細資訊,請參閱 Cryptography Next Generation (CNG) 安全通訊範例。
Alice 透過不安全的公用通道,傳送純文字訊息給 Bob。 並透過安全的私用通道,傳送雜湊訊息給 Bob。 Bob 接收並雜湊該純文字訊息,並將該雜湊與私下交換的雜湊進行比較。 如果這兩個雜湊彼此相符,Bob 可以得知兩件事:
該訊息未經變更。
訊息的傳送者 (Alice) 是可靠的。
若要讓這個系統運作順利,Alice 必須將原始雜湊值藏好,不能讓 Bob 以外的任何人知道。
Alice 透過不安全的公用通道,傳送純文字訊息給 Bob,並將雜湊訊息置放在可公開檢視的網站上。
藉由防止任何人修改雜湊值,這個方法可以防止訊息遭他人修改。 雖然任何人都可以讀取訊息和其雜湊,但是只有 Alice 可以變更該雜湊值。 想要模擬 Alice 的攻擊者需要 Alice 網站的存取權。
前面的方法都不能防止他人讀取 Alice 的訊息,因為訊息是以純文字傳輸的。 完整的安全性通常需要使用數位簽章 (訊息簽署) 和加密。
.NET Framework 提供下列可實作雜湊演算法的類別:
所有安全雜湊演算法 (Secure Hash Algorithm,SHA)、訊息摘要 5 (Message Digest 5,MD5) 和 RIPEMD-160 演算法的 HMAC 變數。
所有 SHA 演算法的 CryptoServiceProvider 實作 (Managed 程式碼包裝函式)。
所有 MD5 和 SHA 演算法的 Cryptography Next Generation (CNG) 實作。
注意事項 |
---|
MD5 設計上的缺陷已在 1996 內發現,並已建議改用 SHA-1。到了 2004 年又發現其他的缺陷,因此 MD5 演算法已不再被視為安全。SHA-1 演算法也已經被發現不具安全性,因此目前建議改用 SHA-2。 |
回到頁首
亂數產生
對許多密碼編譯作業而言,亂數產生是不可或缺的一環。 例如,密碼編譯金鑰需要盡可能的隨機變動,所以它不太可能重現。 密碼編譯亂數產生器所產生的輸出,在計算上,可預測出來的或然率必須小於一半。 因此,任何預測下一個輸出位元的方法絕不會優於隨機猜測法。 .NET Framework 中的類別使用亂數產生器來產生密碼編譯金鑰。
RNGCryptoServiceProvider 類別是亂數產生器演算法的實作。
回到頁首
ClickOnce 資訊清單
在 .NET Framework 3.5 中,下列密碼編譯類別可讓您取得及驗證與應用程式之資訊清單簽章相關的資訊,而這些應用程式是使用 ClickOnce 技術完成部署:
當您使用 ManifestSignatureInformation 類別的 VerifySignature 方法多載時,該類別會取得與資訊清單簽章相關的資訊。
您可以使用 ManifestKinds 列舉型別來指定要驗證的資訊清單。 驗證的結果會是其中一個 SignatureVerificationResult 列舉型別值。
ManifestSignatureInformationCollection 類別提供了通過簽章驗證之 ManifestSignatureInformation 物件的唯讀集合。
此外,下列類別會提供特定的簽章資訊:
StrongNameSignatureInformation 保存資訊清單的強式名稱 (Strong Name) 簽章資訊。
AuthenticodeSignatureInformation 表示資訊清單的 Authenticode 簽章資訊。
TimestampInformation 包含與 Authenticode 簽章上時間戳記相關的資訊。
TrustStatus 提供檢查 Authenticode 簽章是否受信任的簡單方式。
回到頁首
Suite B 支援
.NET Framework 3.5 支援由 National Security Agency (NSA) 所發佈的 Suite B 密碼編譯演算法集合。 如需 Suite B 的詳細資訊,請參閱 NSA Suite B 密碼編譯說明書 (英文)。
其中包含下列演算法:
使用 128、192 和 256 位元的金鑰大小進行加密的先進加密標準 (Advanced Encryption Standard,AES) 演算法。
用於雜湊演算的安全雜湊演算法 SHA-1、SHA-256、SHA-384 和 SHA-512 (最後三種通常會統稱為 SHA-2 群組)。
Elliptic Curve Digital Signature Algorithm (ECDSA),使用 256 位元、384 位元和 521 位元之質數模數的曲線進行簽署。 NSA 文件特別定義了這些曲線,並將其稱為 P-256、P-384 和 P-521。 這個演算法是由 ECDsaCng 類別所提供。 它可讓您使用私密金鑰進行簽署,並以公開金鑰來驗證簽章。
Elliptic Curve Diffie-Hellman (ECDH) 演算法,使用 256 位元、384 位元和 521 位元的質數模數進行金鑰交換和密碼協議。 這個演算法是由 ECDiffieHellmanCng 類別所提供。
已通過聯邦資訊處理標準 (FIPS) 的 AES 實作及 SHA-256、SHA-384 和 SHA-512 等實作的 Managed 程式碼包裝函式,已在新的 AesCryptoServiceProvider、SHA256CryptoServiceProvider、SHA384CryptoServiceProvider 和 SHA512CryptoServiceProvider 類別中提供使用。
回到頁首
Cryptography Next Generation (CNG) 類別
Cryptography Next Generation (CNG) 類別提供了原生 CNG 函式周邊的 Managed 包裝函式 (CNG 是 CryptoAPI 的取代項目)。這些類別會使用 "Cng" 做為其名稱的一部分。 CNG 包裝函式類別的核心是 CngKey 金鑰容器類別,它會抽象化 CNG 金鑰的儲存和使用。 這個類別可讓您安全地儲存金鑰組或公開金鑰,並使用簡單的字串名稱來加以參考。 橢圓曲線架構的 ECDsaCng 簽章類別和 ECDiffieHellmanCng 加密類別可以使用 CngKey 物件。
CngKey 可用於多種不同的其他作業,其中包括開啟、建立、刪除和匯出金鑰。 它也提供存取基礎金鑰控制代碼,以便在直接呼叫原生函式時使用。
.NET Framework 3.5 也包含各種支援 CNG 的類別,如下列所示:
CngProvider 會維護金鑰儲存提供者。
CngAlgorithm 會維護 CNG 演算法。
CngProperty 會維護常用的金鑰屬性。
回到頁首
相關主題
標題 |
說明 |
---|---|
描述在基底類別庫 (Base Class Library) 中實作密碼編譯的方法。 |
|
描述如何使用基底類別庫執行特定的密碼編譯工作。 |
|
示範基本的加密和解密工作。 |
|
描述如何將演算法名稱對應到密碼編譯類別,以及將物件識別項對應到密碼編譯演算法。 |
回到頁首