Microsoft SDL 密碼編譯建議
設計產品時,請使用這項資訊作為參考,以使用 Microsoft 需要自己的產品和服務的相同 API、演算法、通訊協定和密鑰長度。 大部分內容都是以 Microsoft 自己用來建立安全性開發生命週期的內部安全性標準為基礎。
非 Windows 平臺上的開發人員可能會受益於這些建議。 雖然 API 和連結庫名稱可能不同,但涉及演算法選擇、金鑰長度和數據保護的最佳做法在平台之間類似。
安全性通訊協議、演算法和金鑰長度建議
TLS/SSL 版本
產品和服務應使用以密碼編譯方式保護 TLS/SSL 的版本:
- 必須啟用 TLS 1.3。
- 您可以啟用 TLS 1.2 來改善與舊版用戶端的相容性。
- 必須停用 TLS 1.1、TLS 1.0、SSL 3 和 SSL 2
對稱區塊加密、加密模式和初始化向量
封鎖加密
對於使用對稱區塊編碼器的產品︰
- 建議使用進階加密標準 (AES)。
- 所有其他區塊加密,包括 3DES(三重 DES/TDEA),以及 RC4 必須取代用於加密。
針對對稱區塊加密演算法,需要128位的最小密鑰長度,但我們建議支援256位密鑰。 針對新程式代碼建議的唯一區塊加密演算法是 AES(AES-128、AES-192 和 AES-256 都是可接受的,指出 AES-192 在某些處理器上缺乏優化)。
加密模式
對稱演算法可以在各種模式中運作,其中大部分會鏈接在連續純文本和加密文字區塊上的加密作業。
對稱區塊加密應該與下列其中一種加密模式搭配使用:
其他一些加密模式,例如後續的加密模式有實作陷阱,使其更可能不正確使用。 特別是,必須避免電子代碼簿(ECB)的運作模式。 在「串流加密模式」中使用區塊加密來重複使用相同的初始化向量 (IV),例如 CTR 可能會導致顯示加密的數據。 如果使用下列任何模式,建議進行額外的安全性檢閱:
- 輸出意見反應 (OFB)
- 加密意見反應 (CFB)
- 計數器 (CTR)
- 上述「建議」清單上沒有的任何其他專案
初始化向量 (IV)
所有對稱區塊加密也應該搭配密碼編譯強式隨機數作為初始化向量使用。 初始化向量不應該是常數或可述詞值。 如需產生密碼編譯強式隨機數的建議,請參閱隨機數產生器。
執行多個加密作業時,不應該重複使用初始化向量。 重複使用可能會顯示加密數據的相關信息,特別是在使用輸出意見反應 (OFB) 或計數器 (CTR) 等串流加密模式時。
AES-GCM 和 AES-CCM 建議
AES-GCM (Galois/Counter Mode) 和 AES-CCM (Counter with CBC-MAC) 廣泛使用已驗證的加密模式。 它們結合了機密性和完整性保護,使其適用於安全通訊。 然而,它們的脆弱在於非重複使用。 使用相同的 nonce(初始化向量)兩次時,可能會導致災難性後果。
我們建議遵循 NIST SP 800-38D 中所述 的 nonce 指導方針、區塊加密模式操作的建議:Galois/Counter Mode (GCM) 和 GMAC,特別注意有關調用數目上限的第 8.3 節。
另一個選項會針對每個加密的訊息產生唯一的 AES-GCM/CCM 金鑰,有效地將調用數目上限限製為 1。 建議使用此方法來加密待用數據,其中使用計數器或確定您可以追蹤指定密鑰的叫用數目上限是不切實際的。
若要加密待用數據,您也可以考慮使用 AES-CBC 搭配訊息驗證碼 (MAC)作為替代方式,使用 Encrypt-then-MAC 配置,確定您將個別密鑰用於加密和 MAC。
完整性驗證
加密預設提供機密性和完整性保證是常見的誤解。 許多加密演算法不會提供任何完整性檢查,而且可能容易受到竄改攻擊。 必須採取額外的步驟,以確保數據在傳送和接收之後的完整性。
如果您無法使用已驗證的加密演算法搭配相關聯的數據 (AES-GCM),例如 AES-GCM,替代方式是使用 Encrypt-then-MAC 配置來驗證訊息驗證碼 (MAC) 的完整性,以確保您使用個別的密鑰進行加密和 MAC。
使用個別的金鑰進行加密,而 MAC 則很重要。 如果無法儲存這兩個密鑰,有效的替代方法是使用適當的密鑰衍生函式 (KDF),一個用於加密用途,另一個用於 MAC,一個是衍生自主要密鑰。 如需詳細資訊,請參閱 SP 800-108 Rev. 1,建議使用 Pseudorandom 函式進行密鑰衍生 |中國證監會(nist.gov)。
非對稱演算法、金鑰長度和填補模式
RSA
- RSA 可用於加密、金鑰交換和簽章。
- RSA 加密應該使用 OAEP 或 RSA-PSS 填補模式。
- 現有的程式代碼應該只使用 PKCS #1 v1.5 填補模式進行相容性。
- 不建議使用 Null 填補。
- 建議至少使用 2048 位金鑰長度,但建議支援 3072 位金鑰長度。
ECDSA 和 ECDH
- ECDH 型密鑰交換和 ECDSA 型簽章應該使用三個 NIST 核准的曲線之一(P-256、P-384 或 P521)。
- P-256 的支援應視為最小值,但建議支援 P-384。
整數 Diffie-Hellman
- 建議使用金鑰長度 >= 2048 位
- 群組參數應該是已知的具名群組(例如 RFC 7919),或由信任方產生,並在使用之前經過驗證。
金鑰存留期
- 定義所有金鑰的密碼編譯程式。
- 例如:數據加密的對稱密鑰,通常稱為數據加密密鑰或 DEK,對於加密數據,可能具有最多兩年的使用量期間,也稱為「原始程式」使用期間。 您可以定義其具有解密的有效使用期限三年,也稱為收件者使用期間。
- 您應該提供機制,或有取代密鑰的程式,以達到有限的使用中存留期。 在作用中存留期結束后,密鑰不得用來產生新數據(例如,用於加密或簽署),但仍可能用來讀取數據(例如解密或驗證)。
隨機數產生器
當需要隨機性時,所有產品和服務都應該使用密碼編譯保護隨機數產生器。
天然氣
- 使用 BCryptGenRandom 搭配 BCRYPT_USE_SYSTEM_PREFERRED_RNG 旗標。
Win32/64
- 舊版程式代碼可以在核心模式中使用 RtlGenRandom 。
- 新的程式代碼應該使用 BCryptGenRandom 或 CryptGenRandom。
- C 函 式Rand_s() 也建議使用 (在 Windows 上呼叫 CryptGenRandom)。
- Rand_s() 是蘭德() 的安全和高效能的替代品。
- Rand() 不得用於任何密碼編譯應用程式。
.NET
PowerShell
Windows 市集應用程式
- Windows 市集應用程式可以使用 CryptographicBuffer.GenerateRandom 或 CryptographicBuffer.GenerateRandomNumber。
Linux/macOS
- 裝置
/dev/urandom
提供隨機數據的密碼編譯強來源,系統呼叫也一樣getrandom(2)
。
不建議
- 與隨機數產生相關的不安全函式包括:rand、System.Random (.NET)、GetTickCount、GetTickCount64 和 Get-Random (PowerShell Cmdlet)。
- 不允許使用雙橢圓曲線隨機數產生器 (“DUAL_EC_DRBG”) 演算法。
Windows 平台支援的加密連結庫
在 Windows 平臺上,Microsoft 建議使用作業系統內建的加密 API。 在其他平臺上,開發人員可能會選擇評估非平臺加密連結庫以供使用。 一般而言,平臺密碼編譯連結庫會更頻繁地更新,因為它們會隨附於操作系統中,而不是與應用程式搭配使用。
關於平臺與非平臺密碼編譯的任何使用決策,都應該遵循下列需求:
- 連結庫應該是目前不受已知安全性弱點支援的版本。
- 應該支援最新的安全性通訊協議、演算法和金鑰長度。
- (選擇性)連結庫應該能夠支援較舊的安全性通訊協定/演算法,以便只提供回溯相容性。
機器碼
- 密碼編譯基本類型:如果您的版本位於 Windows 上,請盡可能使用 CNG。
- 程式代碼簽章驗證: WinVerifyTrust 是 Windows 平台上驗證程式代碼簽章的支援 API。
- 憑證驗證(用於程式代碼簽署或 SSL/TLS/DTLS 的限制憑證驗證):CAPI2 API;例如, CertGetCertificateChain 和 CertVerifyCertificateChainPolicy。
Managed 程式代碼 (.NET)
- 密碼編譯基本類型:使用 System.Security.Cryptography 命名空間中定義的 API。
- 使用最新版的 .NET 可用。
金鑰衍生函式
金鑰衍生是從共用密碼或現有密碼編譯金鑰衍生密碼編譯密鑰數據的程式。 產品應該使用建議的金鑰衍生函式。 從使用者選擇的密碼衍生金鑰,或驗證系統中記憶體的哈希密碼是本指南未涵蓋的特殊案例:開發人員應該諮詢專家。
下列標準指定建議使用的 KDF 函式:
- NIST SP 800-108(修訂 1):使用虛擬隨機函式進行密鑰衍生的建議。 特別是計數器模式中的 KDF,以 HMAC 作為虛擬隨機函式
- NIST SP 800-56A (修訂 3):使用離散對數密碼編譯配對密鑰建立配置的建議。
若要從現有的金鑰衍生密鑰,請使用 BCryptKeyDerivation API 搭配其中一種演算法:
- BCRYPT_SP800108_CTR_HMAC_ALGORITHM
- BCRYPT_SP80056A_CONCAT_ALGORITHM
若要從共享密碼衍生密鑰(金鑰協定的輸出),請使用 BCryptDeriveKey API 搭配下列其中一種演算法:
- BCRYPT_KDF_SP80056A_CONCAT
- BCRYPT_KDF_HMAC
憑證驗證
使用 TLS 或 DTLS 的產品應該完整驗證其所連線實體的 X.509 憑證。 此程式包含憑證下列部分的驗證:
- 網域名稱。
- 有效日期(開始日期和到期日)。
- 撤銷狀態。
- 使用方式(例如伺服器的「伺服器驗證」、用戶端的「客戶端驗證」)。
- 信任鏈結。 憑證應該鏈結至平臺信任的跟證書授權單位(CA),或由系統管理員明確設定。
如果上述任何驗證測試失敗,產品應該終止與實體的連線。
請勿使用「自我簽署」憑證。 自我簽署本身不會傳達信任、支援撤銷或支援密鑰更新。
密碼編譯哈希函式
產品應該使用 SHA-2 系列哈希演算法(SHA-256、SHA-384 和 SHA-512)。 不允許基於安全性目的截斷密碼編譯哈希到小於128位。 雖然 SHA-256 的使用最低,但建議支援 SHA-384。
MAC/HMAC/索引哈希演算法
訊息驗證碼 (MAC) 是附加到訊息的一條資訊,可供其收件者驗證寄件者的真實性和使用秘密金鑰之訊息的完整性。
只要建議使用所有基礎哈希或對稱加密演算法才能使用 哈希式 MAC(HMAC) 或 區塊加密式 MAC ;目前這包括 HMAC-SHA2 函式(HMAC-SHA256、HMAC-SHA384 和 HMAC-SHA512)。 雖然 HMAC-SHA256 的使用是最低的,但我們建議支援 HMAC-SHA384。
不建議將 HMAC 截斷為小於 128 位。
設計和操作考慮
- 您應該提供必要的機制來取代密碼編譯金鑰。 一旦金鑰到達使用中存留期的結尾,或密碼編譯密鑰遭到入侵,就應該取代密鑰。
- 每當您更新憑證時,都應該使用新的金鑰來更新憑證。
- 使用密碼編譯演算法保護數據的產品應該包含足夠的元數據,以及該內容,以支援在未來移轉至不同的演算法。 此元數據應包含使用的演算法、金鑰大小和填補模式。
- 如需密碼編譯靈活度的詳細資訊,請參閱密碼編譯靈活度一文。
- 如果可用,產品應該使用已建立的平臺式密碼編譯通訊協定,而不是重新實作它們,包括簽署格式(例如,使用標準、現有格式)。
- 請勿向用戶回報密碼編譯作業失敗。 將錯誤傳回遠端呼叫端時(例如,用戶端或用戶端在用戶端伺服器案例中的用戶端),僅使用一般錯誤訊息。
- 避免提供任何不必要的資訊,例如直接報告超出範圍或無效的長度錯誤。 只在伺服器上記錄詳細資訊錯誤,而且只有在啟用詳細信息記錄時。
- 對於包含下列專案的任何設計,強烈建議您進行額外的安全性檢閱:
- 主要著重於安全性的新通訊協定(例如驗證或授權通訊協定)
- 以新式或非標準方式使用密碼編譯的新通訊協定。 範例考慮包括:
- 實作通訊協議的產品是否會呼叫任何密碼編譯 API 或方法,做為通訊協議實作的一部分?
- 通訊協定是否相依於任何其他用於驗證或授權的通訊協定?
- 通訊協定是否會定義密碼編譯專案的儲存格式,例如金鑰?
- 不建議使用自我簽署憑證。 使用自我簽署憑證,例如使用原始密碼編譯密鑰,原本就不會為使用者提供任何基礎來進行信任決策。
- 相反地,使用跟在受信任證書頒發機構單位中的憑證會清楚說明依賴相關聯私鑰的基礎,並在發生安全性失敗時啟用撤銷和更新。