.NET 中的跨平台加密
.NET 中的密碼編譯作業是由作業系統 (OS) 程式庫完成。 此相依性具有下列優點:
- .NET 應用程式受益於 OS 可靠性。 OS 廠商的首要工作是讓密碼編譯程式庫保持安全免於產生弱點。 若要這樣做,其會提供系統管理員應套用的更新。
- 如果 OS 程式庫經過 FIPS 驗證,則 .NET 應用程式可以存取經 FIPS 驗證的演算法。
OS 程式庫的相依性也表示 .NET 應用程式只能使用 OS 支援的密碼編譯功能。 雖然所有平台都支援某些核心功能,但 .NET 支援的功能無法在某些平台上使用。 本文會識別每個平台上支援的功能。
本文假設您已熟悉 .NET 中的密碼編譯。 如需詳細資訊,請參閱 .NET 密碼編譯模型和 .NET 密碼編譯服務。
雜湊和訊息驗證演算法
所有雜湊演算法和雜湊型訊息驗證 (HMAC) 類別,包括 *Managed
類別,都會延遲至 OS 程式庫,但瀏覽器 WASM 上的 .NET 除外。 在瀏覽器 WASM 中,SHA-1、SHA-2-256、SHA-2-384、SHA-2-512 和 HMAC 對等項目是使用 Managed 程式碼來實作。
演算法 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android | 瀏覽器 |
---|---|---|---|---|---|---|
MD5 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
SHA-1 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
SHA-2-256 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
SHA-2-384 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
SHA-2-512 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
SHA-3-2561 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
SHA-3-3841 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
SHA-3-5121 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
SHAKE-1281 | Windows 11 組建 25324+ | OpenSSL 1.1.1+3 | ❌ | ❌ | ❌ | ❌ |
SHAKE-2561 | Windows 11 組建 25324+ | OpenSSL 1.1.1+3 | ❌ | ❌ | ❌ | ❌ |
HMAC-MD5 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
HMAC-SHA-1 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
HMAC-SHA-2-256 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
HMAC-SHA-2-384 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
HMAC-SHA-2-512 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
HMAC-SHA-3-2561 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
HMAC-SHA-3-3841 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
HMAC-SHA-3-5121 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
KMAC-1282 | Windows 11 組建 26016+ | OpenSSL 3.0+ | ❌ | ❌ | ❌ | ❌ |
KMAC-2562 | Windows 11 組建 26016+ | OpenSSL 3.0+ | ❌ | ❌ | ❌ | ❌ |
KMAC-XOF-1282 | Windows 11 組建 26016+ | OpenSSL 3.0+ | ❌ | ❌ | ❌ | ❌ |
KMAC-XOF-2562 | Windows 11 組建 26016+ | OpenSSL 3.0+ | ❌ | ❌ | ❌ | ❌ |
1從 .NET 8 開始提供。
2從 .NET 9 開始提供。
3串流可擴充輸出函式 (XOF) 從 .NET 9 開始提供。 在 Linux 上,這需要 OpenSSL 3.3。
對稱加密
基礎加密和鏈結是由系統程式庫完成。
加密 + 模式 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
AES-CBC | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
AES-ECB | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
AES-CFB8 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
AES-CFB128 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
3DES-CBC | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
3DES-ECB | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
3DES-CFB8 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
3DES-CFB64 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
DES-CBC | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
DES-ECB | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
DES-CFB8 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
RC2-CBC | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
RC2-ECB | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
RC2-CFB | ❌ | ❌ | ❌ | ❌ | ❌ |
已驗證的加密
已驗證的加密 (AE) 支援分別透過 System.Security.Cryptography.AesCcm、System.Security.Cryptography.AesGcm 和 System.Security.Cryptography.ChaCha20Poly1305 類別提供 AES-CCM、AES-GCM 和 ChaCha20Poly1305。
由於驗證的加密需要較新的平台 API 來支援演算法,因此可能並非所有平台上都支援。 演算法類別上的 IsSupported
靜態屬性可用來在執行階段偵測目前平台是否支援演算法。
加密 + 模式 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android | 瀏覽器 |
---|---|---|---|---|---|---|
AES-GCM | ✔️ | ✔️ | ⚠️ | ⚠️ | ✔️ | ❌ |
AES-CCM | ✔️ | ✔️ | ⚠️ | ❌ | ✔️ | ❌ |
ChaCha20Poly1305 | Windows 10 組建 20142+ | OpenSSL 1.1.0+ | ⚠️ | ⚠️ | API 層級 28+ | ❌ |
macOS 上的 AES-CCM
在 macOS 上,系統程式庫不支援對第三方程式碼使用 AES-CCM,因此 AesCcm 類別會使用 OpenSSL 來獲得支援。 macOS 上的使用者必須取得適當的 OpenSSL (libcrypto) 複本,才能讓此類型運作,且其必須位於系統預設會從中載入程式庫的路徑中。 建議您從套件管理員 (例如 Homebrew) 安裝 OpenSSL。
macOS 中包含的 libcrypto.0.9.7.dylib
和 libcrypto.0.9.8.dylib
程式庫是來自舊版的 OpenSSL,因此並不會用到。 libcrypto.35.dylib
、libcrypto.41.dylib
和 libcrypto.42.dylib
程式庫是來自 LibreSSL,因此並不會用到。
macOS 上的 AES-GCM 和 ChaCha20Poly1305
在 macOS 10.15 之前,macOS 不支援對第三方程式碼使用 AES-GCM 或 ChaCha20Poly1305。 在 .NET 8 之前,AesGcm 和 ChaCha20Poly1305 具有與 AES-CCM 相同的需求,且使用者必須安裝 OpenSSL,這些類型才能運作。
從 .NET 8 開始,macOS 上的 .NET 會針對 AES-GCM 和 ChaCha20Poly1305 使用 Apple 的 CryptoKit 架構。 使用者不需要在 macOS 上為 AES-GCM 或 ChaCha20Poly1305 安裝或設定任何其他相依性。
iOS、tvOS 和 MacCatalyst 上的 AES-GCM 和 ChaCha20Poly1305
在 iOS 和 tvOS 13.0 和更新版本以及所有版本的 MacCatalyst 上,AES-GCM 和 ChaCha20Poly1305 的支援從 .NET 9 開始提供。
AES-CCM 金鑰、nonce 和標籤
金鑰大小
AES-CCM 適用於 128、192 和 256 位元金鑰。
Nonce 大小
AesCcm 類別支援 56、64、72、80、88、96 和 104 位元 (7、8、9、10、11、12 和 13 位元組) nonce。
標籤大小
AesCcm 類別支援建立或處理 32、48、64、80、96、112 和 128 位元 (4、8、10、12、14 和 16 位元組) 標籤。
AES-GCM 金鑰、nonce 和標籤
金鑰大小
AES-GCM 適用於 128、192 和 256 位元金鑰。
Nonce 大小
AesGcm 類別僅支援 96 位元 (12 位元組) nonce。
標籤大小:在 Windows 和 Linux 上,AesGcm 類別支援建立或處理 96、104、112、120 和 128 位元 (12、13、14、15 和 16 位元組) 標籤。 在 Apple 平台上,由於 CryptoKit 框架的限制,標記大小限制為 128 位元 (16 位元組)。
ChaCha20Poly1305 金鑰、nonce 和標籤。
ChaCha20Poly1305 針對金鑰、nonce 和驗證標籤具有固定大小。 ChaCha20Poly1305 一律會使用 256 位元金鑰、96 位元 (12 位元組) nonce 和 128 位元 (16 位元組) 標籤。
非對稱密碼編譯
本節包含下列子區段:
RSA
RSA (Rivest–Shamir–Adleman) 金鑰產生是由 OS 程式庫執行,並受限於其大小限制和效能特色。
RSA 金鑰作業是由 OS 程式庫所執行,而可載入的金鑰類型則受限於 OS 需求。
.NET 不會公開「原始」(未填補) RSA 作業。
填補和摘要支援會因平台而異:
填補模式 | Windows (CNG) | Linux (OpenSSL) | macOS | iOS、tvOS、MacCatalyst | Android | Windows (CAPI) |
---|---|---|---|---|---|---|
PKCS1 加密 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
OAEP - SHA-1 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
OAEP - SHA-2 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
OAEP - SHA-32 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
PKCS1 簽章 (MD5、SHA-1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
PKCS1 簽章 (SHA-2) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ⚠️1 |
PKCS1 簽章 (SHA-3)2 | Windows 11 組建 25324+ | OpenSSL 1.1.1+ | ❌ | ❌ | ❌ | ❌ |
PSS | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
1 Windows CryptoAPI (CAPI) 能夠搭配 SHA-2 演算法使用 PKCS1 簽章。 但是,個別 RSA 物件可能會載入不支援的密碼編譯服務提供者 (CSP)。
2 需要 .NET 8。
Windows 上的 RSA
- 每當使用
new RSACryptoServiceProvider()
時,就會使用 Windows CryptoAPI (CAPI)。 - 每當使用
new RSACng()
時,就會使用 Windows 新一代密碼編譯 API (CNG)。 - RSA.Create 所傳回的物件是由 Windows CNG 內部提供。 使用 Windows CNG 是實作詳細資料,且可能會有所變更。
- X509Certificate2 的 GetRSAPublicKey 擴充方法會傳回 RSACng 執行個體。 使用 RSACng 是實作詳細資料,且可能會有所變更。
- X509Certificate2 的 GetRSAPrivateKey 擴充方法目前偏好 RSACng 執行個體,但如果 RSACng 無法開啟金鑰,則將會嘗試 RSACryptoServiceProvider。 慣用的提供者是實作詳細資料,且可能會有所變更。
RSA 原生 interop
.NET 會公開類型,以允許程式與 .NET 密碼編譯程式碼所使用的 OS 程式庫交互操作。 涉及的類型不會在平台之間轉譯,且應該僅在必要時直接使用。
類型 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
RSACryptoServiceProvider | ✔️ | ⚠️1 | ⚠️1 | ⚠️1 | ⚠️1 |
RSACng | ✔️ | ❌ | ❌ | ❌ | ❌ |
RSAOpenSsl | ❌ | ✔️ | ⚠️2 | ❌ | ❌ |
1 在 Windows 上,RSACryptoServiceProvider 可與現有程式搭配使用以獲得相容性。 在此情況下,任何需要 OS Interop 的方法 (例如開啟具名金鑰) 都會擲回 PlatformNotSupportedException。
2 在 macOS 上,如果已安裝 OpenSSL,且可以透過動態程式庫載入找到適當的 libcrypto dylib,則 RSAOpenSsl 運作正常。 如果找不到適當的程式庫,將會擲回例外狀況。
ECDSA
ECDSA (橢圓曲線數位簽章演算法) 金鑰產生是由 OS 程式庫完成,且受限於其大小限制和效能特色。
ECDSA 金鑰曲線是由 OS 程式庫所定義,並受限於其限制。
橢圓曲線 | Windows 10 | Windows 7 - 8.1 | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|---|
NIST P-256 (secp256r1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
NIST P-384 (secp384r1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
NIST P-521 (secp521r1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
Brainpool 曲線 (為具名曲線) | ✔️ | ❌ | ⚠️1 | ❌ | ❌ | ⚠️4 |
其他具名曲線 | ⚠️2 | ❌ | ⚠️1 | ❌ | ❌ | ⚠️4 |
明確曲線 | ✔️ | ❌ | ✔️ | ❌ | ❌ | ✔️ |
匯出或匯入為明確 | ✔️ | ❌3 | ✔️ | ❌3 | ❌3 | ✔️ |
1 Linux 發行版本並未全都支援相同的具名曲線。
2 在 Windows 10 中,已將具名曲線的支援新增至 Windows CNG。 如需詳細資訊,請參閱 CNG 具名橢圓曲線。 除了 Windows 7 中三條曲線外,舊版 Windows 中無法使用具名曲線。
3 使用明確曲線參數匯出需要 OS 程式庫支援,但無法在 Apple 平台或舊版 Windows 上使用。
4 某些曲線的 Android 支援取決於 Android 版本。 Android 散發者也可以選擇從其 Android 組建新增或移除曲線。
ECDSA 原生 Interop
.NET 會公開類型,以允許程式與 .NET 密碼編譯程式碼所使用的 OS 程式庫交互操作。 涉及的類型不會在平台之間轉譯,且應該僅在必要時直接使用。
類型 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
ECDsaCng | ✔️ | ❌ | ❌ | ❌ | ❌ |
ECDsaOpenSsl | ❌ | ✔️ | ⚠️* | ❌ | ❌ |
* 在 macOS 上,如果系統中已安裝 OpenSSL,且可以透過動態程式庫載入找到適當的 libcrypto dylib,則 ECDsaOpenSsl 運作正常。 如果找不到適當的程式庫,將會擲回例外狀況。
ECDH
ECDH (橢圓曲線 Diffie-Hellman) 金鑰產生是由 OS 程式庫完成,並受限於其大小限制和效能特色。
ECDiffieHellman 類別支援 ECDH 計算的「原始」值,以及透過下列金鑰衍生函數:
- HASH(Z)
- HASH(prepend || Z || append)
- HMAC(key, Z)
- HMAC(key, prepend || Z || append)
- HMAC(Z, Z)
- HMAC(Z, prepend || Z || append)
- Tls11Prf(label, seed)
「原始」金鑰衍生是在 .NET 8 中引進。
ECDH 金鑰曲線是由 OS 程式庫所定義,並受限於其限制。
橢圓曲線 | Windows 10 | Windows 7 - 8.1 | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|---|
NIST P-256 (secp256r1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
NIST P-384 (secp384r1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
NIST P-521 (secp521r1) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
Brainpool 曲線 (為具名曲線) | ✔️ | ❌ | ⚠️1 | ❌ | ❌ | ⚠️4 |
其他具名曲線 | ⚠️2 | ❌ | ⚠️1 | ❌ | ❌ | ⚠️4 |
明確曲線 | ✔️ | ❌ | ✔️ | ❌ | ❌ | ✔️ |
匯出或匯入為明確 | ✔️ | ❌3 | ✔️ | ❌3 | ❌3 | ✔️ |
1 Linux 發行版本並未全都支援相同的具名曲線。
2 在 Windows 10 中,已將具名曲線的支援新增至 Windows CNG。 如需詳細資訊,請參閱 CNG 具名橢圓曲線。 除了 Windows 7 中三條曲線外,舊版 Windows 中無法使用具名曲線。
3 使用明確曲線參數匯出需要 OS 程式庫支援,但無法在 Apple 平台或舊版 Windows 上使用。
4 某些曲線的 Android 支援取決於 Android 版本。 Android 散發者也可以選擇從其 Android 組建新增或移除曲線。
ECDH 原生 interop
.NET 會公開類型,以允許程式與 .NET 所使用的 OS 程式庫交互操作。 涉及的類型不會在平台之間轉譯,且應該僅在必要時直接使用。
類型 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
ECDiffieHellmanCng | ✔️ | ❌ | ❌ | ❌ | ❌ |
ECDiffieHellmanOpenSsl | ❌ | ✔️ | ⚠️* | ❌ | ❌ |
* 在 macOS 上,如果已安裝 OpenSSL,且可以透過動態程式庫載入找到適當的 libcrypto dylib,則 ECDiffieHellmanOpenSsl 運作正常。 如果找不到適當的程式庫,將會擲回例外狀況。
DSA
DSA (數位簽章演算法) 金鑰產生是由系統程式庫執行,且受限於其大小限制和效能特色。
函式 | Windows CNG | Linux | macOS | Windows CAPI | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|---|
金鑰建立 (<= 1024 位元) | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ✔️ |
金鑰建立 (> 1024 位元) | ✔️ | ✔️ | ❌ | ❌ | ❌ | ✔️ |
載入金鑰 (<= 1024 位元) | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
載入金鑰 (> 1024 位元) | ✔️ | ✔️ | ⚠️* | ❌ | ❌ | ✔️ |
FIPS 186-2 | ✔️ | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
FIPS 186-3 (SHA-2 簽章) | ✔️ | ✔️ | ❌ | ❌ | ❌ | ✔️ |
* macOS 會載入大於 1024 位元的 DSA 金鑰,但這些金鑰的行為並未定義。 這些金鑰不會根據 FIPS 186-3 運作。
Windows 上的 DSA
- 每當使用
new DSACryptoServiceProvider()
時,就會使用 Windows CryptoAPI (CAPI)。 - 每當使用
new DSACng()
時,就會使用 Windows 新一代密碼編譯 API (CNG)。 - DSA.Create 所傳回的物件是由 Windows CNG 內部提供。 使用 Windows CNG 是實作詳細資料,且可能會有所變更。
- X509Certificate2 的 GetDSAPublicKey 擴充方法會傳回 DSACng 執行個體。 使用 DSACng 是實作詳細資料,且可能會有所變更。
- X509Certificate2 的 GetDSAPrivateKey 擴充方法偏好 DSACng 執行個體,但如果 DSACng 無法開啟金鑰,則將會嘗試 DSACryptoServiceProvider。 慣用的提供者是實作詳細資料,且可能會有所變更。
DSA 原生 interop
.NET 會公開類型,以允許程式與 .NET 密碼編譯程式碼所使用的 OS 程式庫交互操作。 涉及的類型不會在平台之間轉譯,且應該僅在必要時直接使用。
類型 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
DSACryptoServiceProvider | ✔️ | ⚠️1 | ⚠️1 | ❌ | ⚠️1 |
DSACng | ✔️ | ❌ | ❌ | ❌ | ❌ |
DSAOpenSsl | ❌ | ✔️ | ⚠️2 | ❌ | ❌ |
1 在 Windows 上,DSACryptoServiceProvider 可與現有程式搭配使用以獲得相容性。 在此情況下,任何需要系統 Interop 的方法 (例如開啟具名金鑰) 都會擲回 PlatformNotSupportedException。
2 在 macOS 上,如果已安裝 OpenSSL,且可以透過動態程式庫載入找到適當的 libcrypto dylib,則 DSAOpenSsl 運作正常。 如果找不到適當的程式庫,將會擲回例外狀況。
X.509 憑證
.NET 中大部分 X.509 憑證的支援都來自 OS 程式庫。 若要將憑證載入 .NET 中的 X509Certificate2 或 X509Certificate 執行個體,憑證必須由基礎 OS 程式庫載入。
讀取 PKCS12/PFX
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
空的 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
一個憑證,沒有私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
一個憑證,含有私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多個憑證,沒有私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多個憑證,一個私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多個憑證,多個私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
撰寫 PKCS12/PFX
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
空的 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
一個憑證,沒有私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
一個憑證,含有私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多個憑證,沒有私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多個憑證,一個私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
多個憑證,多個私密金鑰 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
暫時載入 | ✔️ | ✔️ | ❌ | ✔️ | ✔️ |
macOS 無法在沒有金鑰鏈物件的情況下載入憑證私密金鑰,這需要寫入磁碟。 會針對 PFX 載入自動建立金鑰鏈,且不再使用時會予以刪除。 因為 X509KeyStorageFlags.EphemeralKeySet 選項表示私密金鑰不應該寫入磁碟,所以判斷 macOS 上的旗標會導致 PlatformNotSupportedException。
撰寫 PKCS7 憑證集合
Windows 和 Linux 都會發出 DER 編碼的 PKCS7 Blob。 macOS 會發出無限長度 CER 編碼的 PKCS7 Blob。
X509Store
在 Windows 上,X509Store 類別是 Windows 憑證存放區 API 的標記法。 這些 API 在 .NET Core 和 .NET 5 中的運作方式與 .NET Framework 相同。
在 Windows 上,X509Store 類別是系統信任決策的投影 (唯讀)、使用者信任決策 (讀寫),以及使用者金鑰儲存體 (讀寫)。
下表顯示每個平台中支援哪些案例。 對於不支援的案例 (資料表中的 ❌),會擲回 CryptographicException。
我的存放區
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
開啟 CurrentUser\My (ReadOnly) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
開啟 CurrentUser\My (ReadWrite) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
開啟 CurrentUser\My (ExistingOnly) | ✔️ | ⚠️ | ✔️ | ✔️ | ✔️ |
開啟 LocalMachine\My | ✔️ | ❌ | ✔️ | ✔️ | ✔️ |
在 Linux 上,會在第一次寫入時建立存放區,且預設沒有任何使用者存放區存在,因此使用 ExistingOnly
開啟 CurrentUser\My
時可能會失敗。
在 macOS 上,CurrentUser\My
存放區是使用者的預設金鑰鏈,預設為 login.keychain
。 LocalMachine\My
存放區是 System.keychain
。
根存放區
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
開啟 CurrentUser\Root (ReadOnly) | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
開啟 CurrentUser\Root (ReadWrite) | ✔️ | ✔️ | ❌ | ❌ | ❌ |
開啟 CurrentUser\Root (ExistingOnly) | ✔️ | ⚠️ | ✔️ (如果 ReadOnly) | ❌ | ✔️ (如果 ReadOnly) |
開啟 LocalMachine\Root (ReadOnly) | ✔️ | ✔️ | ✔️ | ❌ | ✔️ |
開啟 LocalMachine\Root (ReadWrite) | ✔️ | ❌ | ❌ | ❌ | ❌ |
開啟 LocalMachine\Root (ExistingOnly) | ✔️ | ⚠️ | ✔️ (如果 ReadOnly) | ❌ | ✔️ (如果 ReadOnly) |
在 Linux 上,LocalMachine\Root
存放區是 OpenSSL 預設路徑中 CA 套件組合的解譯。
在 macOS 上,CurrentUser\Root
存放區是使用者信任網域 SecTrustSettings
結果的解譯。 LocalMachine\Root
存放區是管理員和系統信任網域 SecTrustSettings
結果的解譯。
中繼存放區
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
開啟 CurrentUser\Intermediate (ReadOnly) | ✔️ | ✔️ | ✔️ | ❌ | ❌ |
開啟 CurrentUser\Intermediate (ReadWrite) | ✔️ | ✔️ | ❌ | ❌ | ❌ |
開啟 CurrentUser\Intermediate (ExistingOnly) | ✔️ | ⚠️ | ✔️ (如果 ReadOnly) | ❌ | ❌ |
開啟 LocalMachine\Intermediate (ReadOnly) | ✔️ | ✔️ | ✔️ | ❌ | ❌ |
開啟 LocalMachine\Intermediate (ReadWrite) | ✔️ | ❌ | ❌ | ❌ | ❌ |
開啟 LocalMachine\Intermediate (ExistingOnly) | ✔️ | ⚠️ | ✔️ (如果 ReadOnly) | ❌ | ❌ |
在 Linux 上,CurrentUser\Intermediate
存放區會在成功 X509Chain 組建的授權單位資訊存取記錄下載中繼 CA 時做為快取。 LocalMachine\Intermediate
存放區是 OpenSSL 預設路徑中 CA 套件組合的解譯。
在 macOS 上,CurrentUser\Intermediate
存放區會被視為自訂存放區。 新增至此存放區的憑證不會影響 X.509 鏈結建置。
不允許的存放區
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
開啟 CurrentUser\Disallowed (ReadOnly) | ✔️ | ⚠️ | ✔️ | ✔️ | ✔️ |
開啟 CurrentUser\Disallowed (ReadWrite) | ✔️ | ⚠️ | ❌ | ❌ | ❌ |
開啟 CurrentUser\Disallowed (ExistingOnly) | ✔️ | ⚠️ | ✔️ (如果 ReadOnly) | ✔️ (如果 ReadOnly) | ✔️ (如果 ReadOnly) |
開啟 LocalMachine\Disallowed (ReadOnly) | ✔️ | ❌ | ✔️ | ✔️ | ✔️ |
開啟 LocalMachine\Disallowed (ReadWrite) | ✔️ | ❌ | ❌ | ❌ | ❌ |
開啟 LocalMachine\Disallowed (ExistingOnly) | ✔️ | ❌ | ✔️ (如果 ReadOnly) | ✔️ (如果 ReadOnly) | ✔️ (如果 ReadOnly) |
在 Linux 上,不會在鏈結建置中使用 Disallowed
存放區,且嘗試將內容新增至其中會導致 CryptographicException。 如果已取得內容,則會在開啟 Disallowed
存放區時擲回 CryptographicException。
在 macOS 上,針對信任設定為 Always Deny
的憑證,CurrentUser\Disallowed 和 LocalMachine\Disallowed 存放區是適當 SecTrustSettings 結果的解譯。
不存在的存放區
案例 | Windows | Linux | macOS | iOS、tvOS、MacCatalyst | Android |
---|---|---|---|---|---|
開啟不存在的存放區 (ExistingOnly) | ❌ | ❌ | ❌ | ❌ | ❌ |
開啟 CurrentUser 不存在的存放區 (ReadWrite) | ✔️ | ✔️ | ⚠️ | ❌ | ❌ |
開啟 LocalMachine 不存在的存放區 (ReadWrite) | ✔️ | ❌ | ❌ | ❌ | ❌ |
在 macOS 上,只有 CurrentUser
位置才支援使用 X509Store API 建立自訂存放區。 其會在使用者的金鑰鏈目錄中建立沒有密碼的新金鑰鏈 (~/Library/Keychains)。 若要使用密碼建立金鑰鏈,可以使用 P/Invoke SecKeychainCreate
。 同樣地,SecKeychainOpen
可用來在不同的位置開啟金鑰鏈。 結果 IntPtr
可以傳遞至 new X509Store(IntPtr)
,以取得可讀取/寫入的存放區,受限於目前使用者的權限。
X509Chain
macOS 不支援離線 CRL 使用率,因此會將 X509RevocationMode.Offline
視為 X509RevocationMode.Online
。
macOS 不支援 CRL (憑證撤銷清單) /OCSP (線上憑證狀態通訊協定) / AIA (授權單位資訊存取) 下載的使用者起始逾時,因此會忽略 X509ChainPolicy.UrlRetrievalTimeout
。