.NET Core と .NET 5 でのクロスプラットフォームの暗号化

.NET Core と .NET 5 以降の暗号化操作は、オペレーティング システム (OS) ライブラリによって行われます。 この依存関係には、次の利点があります。

  • .NET アプリが、信頼できる OS の恩恵を受けられます。 OS ベンダーにとって、暗号化ライブラリを脆弱性から保護することは高い優先順位です。 そのために、システム管理者が適用する必要がある更新プログラムを提供しています。
  • OS ライブラリが FIPS 検証済みの場合、.NET アプリから FIPS 検証アルゴリズムにアクセスできます。

OS ライブラリに依存するということは、.NET アプリから、OS でサポートされる暗号化機能のみを使用できるということも意味します。 特定のコア機能がすべてのプラットフォームによってサポートされているのに対して、.NET によってサポートされている一部の機能は一部のプラットフォームで使用できません。 この記事では、各プラットフォームでサポートされている機能について説明します。

この記事では、.NET での暗号化に精通していることを前提としています。 詳細については、「.NET 暗号化モデル」と「.NET 暗号化サービス」を参照してください。

ハッシュ アルゴリズム

*Managed クラスを含むすべてのハッシュ アルゴリズムとハッシュベースのメッセージ認証 (HMAC) クラスは、OS ライブラリに従います。 さまざまな OS ライブラリがあり、パフォーマンスは異なりますが、互換性はあるはずです。

対称暗号化

基になる暗号とチェーンはシステム ライブラリによって行われ、そのすべてが、すべてのプラットフォームでサポートされています。

暗号 + モード Windows Linux macOS
AES-CBC ✔️ ✔️ ✔️
AES-ECB ✔️ ✔️ ✔️
3DES-CBC ✔️ ✔️ ✔️
3DES-ECB ✔️ ✔️ ✔️
DES-CBC ✔️ ✔️ ✔️
DES-ECB ✔️ ✔️ ✔️

認証付き暗号

AES-CCM および AES-GCM に対する認証付き暗号 (AE) のサポートは、System.Security.Cryptography.AesCcm および System.Security.Cryptography.AesGcm クラスを介して提供されています。

Windows および Linux では、AES-CCM と AES-GCM の実装は OS ライブラリによって提供されています。

macOS 上の AES-CCM と AES-GCM

macOS では、サード パーティのコードのための AES-CCM または AES GCM がシステム ライブラリによってサポートされていないため、サポートのため、AesCcm および AesGcm クラスによって OpenSSL が使用されています。 macOS のユーザーは、これらの種類を機能させるために OpenSSL (libcrypto) の適切なコピーを取得する必要があり、既定では、システムによってライブラリが読み込まれるパス内にある必要があります。 Homebrew などのパッケージ マネージャーから OpenSSL をインストールすることをお勧めします。

macOS に含まれる libcrypto.0.9.7.dylib および libcrypto.0.9.8.dylib は、以前のバージョンの OpenSSL のライブラリであり、今後は使用されません。 libcrypto.35.dyliblibcrypto.41.dylib、および libcrypto.42.dylib は、LibreSSL のライブラリであり、今後は使用されません。

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 のみがサポートされています。

  • タグのサイズ

    AesGcm クラスにより、96、104、112、120、および 128 ビット (12、13、14、15、および 16 バイト) タグの作成または処理がサポートされています。

非対称暗号化

このセクションには、次のサブセクションが含まれています。

RSA

RSA (Rivest–Shamir–Adleman) のキー生成は OS ライブラリによって実行され、そのサイズの制限とパフォーマンス特性が適用されます。

RSA のキー操作は OS ライブラリによって実行され、読み込むことができるキーの種類は OS 要件に従います。

.NET では、"生" の (パディングされていない) RSA 操作は公開されていません。

OS ライブラリは、暗号化と暗号化の解除のパディングに使用されます。 すべてのプラットフォームで同じパディング オプションがサポートされているわけではありません。

パディング モード Windows (CNG) Linux (OpenSSL) macOS Windows (CAPI)
PKCS1 暗号化 ✔️ ✔️ ✔️ ✔️
OAEP - SHA-1 ✔️ ✔️ ✔️ ✔️
OAEP - SHA-2 (SHA256、SHA384、SHA512) ✔️ ✔️ ✔️
PKCS1 署名 (MD5、SHA-1) ✔️ ✔️ ✔️ ✔️
PKCS1 署名 (SHA-2) ✔️ ✔️ ✔️ ⚠️*
PSS ✔️ ✔️ ✔️

* Windows CryptoAPI (CAPI) は、SHA-2 アルゴリズムを使用した PKCS1 署名が可能です。 ただし、個々の RSA オブジェクトが、それをサポートしていない暗号化サービス プロバイダー (CSP) に読み込まれる場合があります。

Windows 上の RSA

  • new RSACryptoServiceProvider() が使用されるたびに、Windows CryptoAPI (CAPI) が使用されます。
  • new RSACng() が使用されるたびに、Windows Cryptography API Next Generation (CNG) が使用されます。
  • RSA.Create から返されるオブジェクトは、内部的には Windows CNG が動作します。 この Windows CNG の使用は実装の 1 項目であり、変更される可能性があります。
  • X509Certificate2GetRSAPublicKey 拡張メソッドから、RSACng インスタンスが返されます。 この RSACng の使用は実装の 1 項目であり、変更される可能性があります。
  • X509Certificate2GetRSAPrivateKey 拡張メソッドでは現在 RSACng インスタンスが優先されますが、RSACng がキーを開けない場合は、RSACryptoServiceProvider が試行されます。 優先プロバイダーは実装の 1 項目であり、変更される可能性があります。

RSA のネイティブな相互運用

.NET 暗号化コードによって使用される OS ライブラリとの相互運用をプログラムで可能にする種類が .NET によって公開されています。 関連する種類はプラットフォーム間で変換されないため、必要な場合にのみ直接使用する必要があります。

Type Windows Linux macOS
RSACryptoServiceProvider ✔️ ⚠️1 ⚠️1
RSACng ✔️
RSAOpenSsl ✔️ ⚠️2

1 macOS と Linux では、既存のプログラムとの互換性のために RSACryptoServiceProvider を使用できます。 この場合、名前付きキーを開くなど、OS の相互運用を必要とするメソッドから PlatformNotSupportedException がスローされます。

2 macOS では、OpenSSL がインストールされていて、ダイナミック ライブラリを読み込むことで適切な libcrypto dylib を検出できる場合に RSAOpenSsl が機能します。 適切なライブラリを検出できない場合は、例外がスローされます。

ECDSA

ECDSA (楕円曲線デジタル署名アルゴリズム) のキー生成は OS ライブラリによって行われ、そのサイズの制限とパフォーマンス特性が適用されます。

ECDSA のキー曲線は OS ライブラリによって定義され、その制限が適用されます。

楕円曲線 Windows 10 Windows 7 から 8.1 Linux macOS
NIST P-256 (secp256r1) ✔️ ✔️ ✔️ ✔️
NIST P-384 (secp384r1) ✔️ ✔️ ✔️ ✔️
NIST P-521 (secp521r1) ✔️ ✔️ ✔️ ✔️
Brainpool 曲線 (名前付き曲線として) ✔️ ⚠️1
その他の名前付き曲線 ⚠️2 ⚠️1
明示的な曲線 ✔️ ✔️
明示的にエクスポートまたはインポート ✔️ 3 ✔️ 3

1 すべての Linux ディストリビューションで、同じ名前付き曲線がサポートされているわけではありません。

2 名前付き曲線のサポートは、Windows 10 の Windows CNG に追加されました。 詳細については、CNG 名前付き楕円曲線に関する記事をご覧ください。 名前付き曲線は、Windows 7 における 3 つの曲線を除き、以前のバージョンの Windows では使用できません。

3 明示的な曲線パラメーターを使用してエクスポートするには、OS ライブラリのサポートが必要です。これは、macOS または以前のバージョンの Windows では使用できません。

ECDSA のネイティブな相互運用

.NET 暗号化コードによって使用される OS ライブラリとの相互運用をプログラムで可能にする種類が .NET によって公開されています。 関連する種類はプラットフォーム間で変換されないため、必要な場合にのみ直接使用する必要があります。

Type Windows Linux macOS
ECDsaCng ✔️
ECDsaOpenSsl ✔️ ⚠️*

* macOS では、OpenSSL がシステムにインストールされていて、ダイナミック ライブラリを読み込むことで適切な libcrypto dylib を検出できる場合に ECDsaOpenSsl が機能します。 適切なライブラリを検出できない場合は、例外がスローされます。

ECDH

ECDH (Elliptic Curve 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)

ECDH のキー曲線は OS ライブラリによって定義され、その制限が適用されます。

楕円曲線 Windows 10 Windows 7 から 8.1 Linux macOS
NIST P-256 (secp256r1) ✔️ ✔️ ✔️ ✔️
NIST P-384 (secp384r1) ✔️ ✔️ ✔️ ✔️
NIST P-521 (secp521r1) ✔️ ✔️ ✔️ ✔️
Brainpool 曲線 (名前付き曲線として) ✔️ ⚠️1
その他の名前付き曲線 ⚠️2 ⚠️1
明示的な曲線 ✔️ ✔️
明示的にエクスポートまたはインポート ✔️ 3 ✔️ 3

1 すべての Linux ディストリビューションで、同じ名前付き曲線がサポートされているわけではありません。

2 名前付き曲線のサポートは、Windows 10 の Windows CNG に追加されました。 詳細については、CNG 名前付き楕円曲線に関する記事をご覧ください。 名前付き曲線は、Windows 7 における 3 つの曲線を除き、以前のバージョンの Windows では使用できません。

3 明示的な曲線パラメーターを使用してエクスポートするには、OS ライブラリのサポートが必要です。これは、macOS または以前のバージョンの Windows では使用できません。

ECDH のネイティブな相互運用

.NET によって使用される OS ライブラリとの相互運用をプログラムで可能にする種類が .NET によって公開されています。 関連する種類はプラットフォーム間で変換されないため、必要な場合にのみ直接使用する必要があります。

Type Windows Linux macOS
ECDiffieHellmanCng ✔️
ECDiffieHellmanOpenSsl ✔️ ⚠️*

* macOS では、OpenSSL がインストールされていて、ダイナミック ライブラリを読み込むことで適切な libcrypto dylib を検出できる場合に ECDiffieHellmanOpenSsl が機能します。 適切なライブラリを検出できない場合は、例外がスローされます。

DSA

DSA (デジタル署名アルゴリズム) のキー生成はシステム ライブラリによって実行され、そのサイズの制限とパフォーマンス特性が適用されます。

機能 Windows CNG Linux macOS Windows CAPI
キーの作成 (1024 ビット以下) ✔️ ✔️ ✔️
キーの作成 (1024 ビットより大きい) ✔️ ✔️
キーの読み込み (1024 ビット以下) ✔️ ✔️ ✔️ ✔️
キーの読み込み (1024 ビットより大きい) ✔️ ✔️ ⚠️*
FIPS 186-2 ✔️ ✔️ ✔️ ✔️
FIPS 186-3 (SHA-2 署名) ✔️ ✔️

* 1024 ビットより大きい DSA キーは、macOS によって読み込まれますが、これらのキーの動作は定義されていません。 FIPS 186-3 に従って動作しません。

Windows 上の DSA

  • new DSACryptoServiceProvider() が使用されるたびに、Windows CryptoAPI (CAPI) が使用されます。
  • new DSACng() が使用されるたびに、Windows Cryptography API Next Generation (CNG) が使用されます。
  • DSA.Create から返されるオブジェクトは、内部的には Windows CNG が動作します。 この Windows CNG の使用は実装の 1 項目であり、変更される可能性があります。
  • X509Certificate2GetDSAPublicKey 拡張メソッドから、DSACng インスタンスが返されます。 この DSACng の使用は実装の 1 項目であり、変更される可能性があります。
  • X509Certificate2GetDSAPrivateKey 拡張メソッドでは DSACng インスタンスが優先されますが、DSACng がキーを開けない場合は、DSACryptoServiceProvider が試行されます。 優先プロバイダーは実装の 1 項目であり、変更される可能性があります。

DSA のネイティブな相互運用

.NET 暗号化コードによって使用される OS ライブラリとの相互運用をプログラムで可能にする種類が .NET によって公開されています。 関連する種類はプラットフォーム間で変換されないため、必要な場合にのみ直接使用する必要があります。

Type Windows Linux macOS
DSACryptoServiceProvider ✔️ ⚠️1 ⚠️1
DSACng ✔️
DSAOpenSsl ✔️ ⚠️2

1 macOS と Linux では、既存のプログラムとの互換性のために DSACryptoServiceProvider を使用できます。 この場合、名前付きキーを開くなど、システムの相互運用を必要とするメソッドから PlatformNotSupportedException がスローされます。

2 macOS では、OpenSSL がインストールされていて、ダイナミック ライブラリを読み込むことで適切な libcrypto dylib を検出できる場合に DSAOpenSsl が機能します。 適切なライブラリを検出できない場合は、例外がスローされます。

X.509 証明書

.NET での X.509 証明書のサポートの大部分は、OS ライブラリから提供されます。 証明書を .NET の X509Certificate2 または X509Certificate インスタンスに読み込むには、証明書が、基盤となる OS ライブラリによって読み込まれる必要があります。

PKCS12/PFX を読み取る

シナリオ Windows Linux macOS
Empty ✔️ ✔️ ✔️
証明書が 1 つ、秘密キーなし ✔️ ✔️ ✔️
証明書が 1 つ、秘密キーあり ✔️ ✔️ ✔️
証明書が複数、秘密キーなし ✔️ ✔️ ✔️
証明書が複数、秘密キーが 1 つ ✔️ ✔️ ✔️
証明書が複数、秘密キーが複数 ✔️ ⚠️* ✔️

* .NET 5 以降で利用可能です。

PKCS12/PFX を書き込む

シナリオ Windows Linux macOS
Empty ✔️ ✔️ ⚠️*
証明書が 1 つ、秘密キーなし ✔️ ✔️ ⚠️*
証明書が 1 つ、秘密キーあり ✔️ ✔️ ✔️
証明書が複数、秘密キーなし ✔️ ✔️ ⚠️*
証明書が複数、秘密キーが 1 つ ✔️ ✔️ ✔️
証明書が複数、秘密キーが複数 ✔️ ⚠️* ✔️
短期の読み込み ✔️ ✔️ ⚠️*

* .NET 5 以降で利用可能です。

macOS では、キーチェーン オブジェクトがないと、ディスクへの書き込みが必要な秘密キーを読み込むことができません。 キーチェーンは PFX 読み込み用に自動的に作成され、使用されなくなると削除されます。 X509KeyStorageFlags.EphemeralKeySet オプションは、秘密キーがディスクに書き込まれてはいけないことを意味するため、macOS でそのフラグをアサートすると PlatformNotSupportedException が発生します。

PKCS7 証明書コレクションを書き込む

Windows と Linux では両方とも DER エンコードされた PKCS7 BLOB が生成されます。 macOS では、長さが不定の CER エンコードされた PKCS7 BLOB が生成されます。

X509Store

Windows では、X509Store クラスは Windows 証明書ストア API を表します。 これらの API は、.NET Framework の場合と同様に、.NET Core および .NET 5 でも動作します。

Linux では、X509Store クラスは、システムの信頼の決定 (読み取り専用)、ユーザー信頼の決定 (読み取り/書き込み)、およびユーザー キー ストレージ (読み取り/書き込み) のプロジェクションです。

macOS では、X509Store クラスは、システムの信頼の決定 (読み取り専用)、ユーザー信頼の決定 (読み取り専用)、およびユーザー キー ストレージ (読み取り/書き込み) のプロジェクションです。

次の表は、各プラットフォームでサポートされているシナリオを示しています。 サポートされていないシナリオ (表の ❌) の場合、CryptographicException がスローされます。

個人用ストア

シナリオ Windows Linux macOS
CurrentUser\My を開く (ReadOnly) ✔️ ✔️ ✔️
CurrentUser\My を開く (ReadWrite) ✔️ ✔️ ✔️
CurrentUser\My を開く (ExistingOnly) ✔️ ⚠️ ✔️
LocalMachine\My を開く ✔️ ✔️

Linux では、最初の書き込み時にストアが作成され、既定ではユーザー ストアが存在しないため、CurrentUser\MyExistingOnly で開くとエラーになるおそれがあります。

macOS では、CurrentUser\My ストアがユーザーの既定のキーチェーンであり、既定では login.keychain です。 LocalMachine\My ストアは System.keychain です。

ルート ストア

シナリオ Windows Linux macOS
CurrentUser\Root を開く (ReadOnly) ✔️ ✔️ ✔️
CurrentUser\Root を開く (ReadWrite) ✔️ ✔️
CurrentUser\Root を開く (ExistingOnly) ✔️ ⚠️ ✔️ (ReadOnly の場合)
LocalMachine\Root を開く (ReadOnly) ✔️ ✔️ ✔️
LocalMachine\Root を開く (ReadWrite) ✔️
LocalMachine\Root を開く (ExistingOnly) ✔️ ⚠️ ✔️ (ReadOnly の場合)

Linux では、LocalMachine\Root ストアは、OpenSSL の既定のパス内にある CA バンドルを解釈したものです。

macOS では、CurrentUser\Root ストアは、ユーザー信頼ドメインの SecTrustSettings の結果を解釈したものです。 LocalMachine\Root ストアは、管理者およびシステム信頼ドメインの SecTrustSettings の結果を解釈したものです。

中間ストア

シナリオ Windows Linux macOS
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 バンドルを解釈したものです。

許可されないストア

シナリオ Windows Linux macOS
CurrentUser\Disallowed を開く (ReadOnly) ✔️ ⚠️ ✔️
CurrentUser\Disallowed を開く (ReadWrite) ✔️ ⚠️
CurrentUser\Disallowed を開く (ExistingOnly) ✔️ ⚠️ ✔️ (ReadOnly の場合)
LocalMachine\Disallowed を開く (ReadOnly) ✔️ ✔️
LocalMachine\Disallowed を開く (ReadWrite) ✔️
LocalMachine\Disallowed を開く (ExistingOnly) ✔️ ✔️ (ReadOnly の場合)

Linux では、Disallowed ストアはチェーンのビルドでは使用されず、そのストアにコンテンツを追加しようとすると、CryptographicException が発生します。 コンテンツが既に取得されている場合に Disallowed ストアを開くと、CryptographicException がスローされます。

macOS では、CurrentUser\Disallowed および LocalMachine\Disallowed ストアは、信頼が Always Deny に設定されている証明書の適切な SecTrustSettings 結果を解釈したものです。

存在しないストア

シナリオ Windows Linux macOS
存在しないストアを開く (ExistingOnly)
CurrentUser の存在しないストアを開く (ReadWrite) ✔️ ✔️ ⚠️
LocalMachine の存在しないストアを開く (ReadWrite) ✔️

macOS では、X509Store API を使用したカスタム ストアの作成は、CurrentUser の場所でのみサポートされています。 これにより、ユーザーのキーチェーン ディレクトリ ( ~/Library/Keychains) にパスワードなしの新しいキーチェーンが作成されます。 パスワードありのキーチェーンを作成するには、SecKeychainCreate への P/Invoke を使用できます。 同様に、SecKeychainOpen を使用して、異なる場所でキーチェーンを開くこともできます。 結果として得られる IntPtrnew X509Store(IntPtr) に渡して、現在のユーザーのアクセス許可に従って、読み取り/書き込み可能なストアを取得できます。

X509Chain

オフライン CRL の使用は macOS によりサポートされていないため、X509RevocationMode.OfflineX509RevocationMode.Online として扱われます。

CRL (証明書失効リスト)/OCSP (オンライン証明書状態プロトコル)/AIA (機関情報アクセス) のダウンロードでユーザーが開始するタイムアウトは macOS によりサポートされていないため、X509ChainPolicy.UrlRetrievalTimeout は無視されます。

その他のリソース