Share via


Microsoft SDLの暗号化に関する推奨事項

はじめに

このドキュメントには、Microsoft プラットフォームで暗号化を使用する際の推奨事項とベスト プラクティスが記載されています。 ここで説明する内容の多くは、セキュリティ開発ライフサイクルの作成に使用される Microsoft 独自の内部セキュリティ標準から要約あるいは集約されたものです。 これは Microsoft が独自の製品およびサービスに求めるものと同じ API、アルゴリズム、プロトコル、およびキーの長さを使用するように製品を設計する際に参照として使用するためのものです。

Windows 以外のプラットフォームの開発者も、これらの推奨事項を活用できます。 API とライブラリの名前は異なる場合がありますが、アルゴリズムの選択、キーの長さ、データ保護に関するベスト プラクティスは、プラットフォーム間で類似しています。

セキュリティ プロトコル、アルゴリズム、およびキーの長さに関する推奨事項

SSL/TLSのバージョン

製品とサービスでは、暗号として安全な SSL/TLSのバージョンを使用する必要があります。

  • TLS 1.2を有効にする必要があります

  • TLS 1.1 と TLS 1.0 は、旧バージョンとの互換性のためにのみ有効にする必要があります

  • SSL3と SSL 2を既定で無効にする必要があります

対称ブロック暗号、暗号モード、および初期化ベクトル

ブロック暗号

対称ブロック暗号を使用する製品では、次の点に注意してください。

  • 新しいコードには、Advanced Encryption Standard (AES) が推奨されます。

  • 3DES (Three-key triple Data Encryption Standard) は、下位互換性を確保するために既存のコードで許容されます。

  • RC2、DES、2-key 3DES、DESX、Skipjack など、他のすべてのブロック暗号は、古いデータの復号化にのみ使用し、暗号化に使用する場合は置き換える必要があります。

対称ブロック暗号化アルゴリズムでは、128 ビットの最小キー長が推奨されます。 新しいコードに推奨される唯一のブロック暗号化アルゴリズムは AES です (AES-128、AES-192、および AES-256 はすべて許容されますが、AES-192 では一部のプロセッサで最適化されないことに注意してください)。 現在、three-key 3DES は、既存のコードで既に使用されている場合には許容されますが、AES に移行することをお勧めします。 DES、DESX、RC2、Skipjack は安全と見なされなくなりました。 これらのアルゴリズムは、下位互換性を確保するために既存のデータの復号化にのみ使用します。データは、推奨されるブロック暗号を使用して再暗号化する必要があります。

"暗号モード"

対称アルゴリズムはさまざまなモードで動作でき、そのほとんどは、プレーンテキストと暗号化テキストの後続のブロックに対する暗号化操作とリンクします。

対称ブロック暗号は、次のいずれかの暗号モードで使用する必要があります。

次に示すような他のいくつかの暗号モードには実装上の落とし穴があるため、誤って使用される可能性が高くなります。 特に、電子コード ブック (ECB) 動作モードは避ける必要があります。 CTR などの "ストリーム暗号モード"のブロック暗号で同じ初期化ベクトル (IV)を再利用すると、暗号化されたデータが漏洩する可能性があります。 以下のいずれかのモードを使用する場合は、追加のセキュリティ レビューをお勧めします。

  • 出力フィードバック (OFB)

  • 暗号フィードバック (CFB)

  • Counter (CTR)

  • Counter with CBC-MAC (CCM)

  • Galois/Counter Mode (GCM)

  • 上記の "推奨される" リストにないその他のもの

"初期化ベクトル (IV)"

すべての対称ブロック暗号では、暗号強度の高い乱数を初期化ベクトルとして使用する必要もあります。 初期化ベクトルを定数値にすることはできません。 暗号強度の高い乱数を生成する方法については、「乱数ジェネレーター」を参照してください。

複数の暗号化操作を実行する場合、初期化ベクトルを再利用することは避けてください。これにより、特に出力フィードバック (OFB) や Counter (CTR) などのストリーミング暗号モードを使用する場合に、暗号化されているデータに関する情報が漏洩する可能性があります。

非対称アルゴリズム、キーの長さ、パディング モード

RSA

  • RSA は、暗号化、キー交換、署名に使用する必要があります。

  • RSA 暗号化では、OAEPまたはRSA-PSSのパディング モードを使用する必要があります。 既存のコードでは、互換性の確保のみを目的として、PKCS #1 v1.5 パディング モードを使用できます。

  • null パディングは使用しないことをお勧めします。

  • 2048 ビット以上のキーの長さが推奨されます

ECDSA

  • ECDSA では 256 ビット以上のキーが推奨されます

  • ECDSA ベースの署名では、NIST が承認した3つの曲線 (P-256、P-384、P521)のいずれかを使用する必要があります。

ECDH

  • ECDH では 256 ビット以上のキーが推奨されます

  • ECDH ベースのキー交換では、NIST が承認した3つの曲線 (P-256、P-384、P521)のいずれかを使用する必要があります。

"整数の Diffie-Hellman"

  • 2048 ビット以上のキーの長さが推奨されます

  • グループ パラメーターは、既知の名前付きグループ (RFC 7919 など) であるか、信頼された相手によって生成され使用前に認証されている必要があります

キーの有効期間

  • すべての非対称キーには最大5年の有効期間が必要であり、有効期間を1年にすることをお勧めします。

  • すべての対称キーには最大3年の有効期間が必要であり、有効期間を1年にすることをお勧めします。

  • 有効期間が制限されるようにするには、キーを置き換えるためのメカニズムを提供するかプロセスを用意する必要があります。 有効期間が終了した後は、新しいデータを生成する (たとえば暗号化や署名を行う) ためにキーを使用することはできませんが、データの読み取り (暗号化解除や検証など)のために使用することはできます。

乱数ジェネレーター

ランダム性が必要な場合は、すべての製品とサービスで暗号として安全な乱数ジェネレーターを使用する必要があります。

CNG

  • BCryptGenRandomをBCRYPT_USE_SYSTEM_PREFERRED_RNG フラグとともに使用する

CAPI

  • CryptGenRandomを使用して、ランダムな値を生成します。

Win32/64

  • レガシ コードでは、カーネル モードで RtlGenRandomを使用できます

  • 新しいコードでは、BCryptGenRandomまたはCryptGenRandomを使用する必要があります。

  • C 関数 Rand_s() も推奨される (Windows では CryptGenRandomを呼び出します)

  • Rand_s() は、Rand()の安全でパフォーマンスの高い Rand()の代替手段です。 Rand() はすべての暗号化アプリケーションで使用すべきではありませんが、内部テストに限り問題ありません。

  • カーネル モードのコードには、SystemPrng 関数を使用することをお勧めします。

.NET

"Windows ストア アプリ"

非推奨

  • 乱数生成に関する安全でない関数 (randSystem.Random (.NET)、GetTickCountGetTickCount64 など)

  • 双対楕円曲線乱数ジェネレーター (「DUAL_EC_DRBG」) アルゴリズムの使用は推奨されません。

Windows プラットフォームでサポートされている暗号化ライブラリ

Windows プラットフォームでは、オペレーティング システムに組み込まれている暗号化 APIを使用することをお勧めします。 他のプラットフォームでは、開発者はプラットフォーム以外の暗号化ライブラリの使用を評価することを選択できます。 一般に、プラットフォーム暗号化ライブラリは、アプリケーションにバンドルされるのではなく、オペレーティング システムの一部として付属しているため、より頻繁に更新されます。

プラットフォームとプラットフォーム以外の暗号化に関する使用上のすべての決定は、次の要件に従って行われる必要があります。

  1. ライブラリは、セキュリティ上の既知の脆弱性がない現在サポートされているバージョンである必要があります

  2. 最新のセキュリティ プロトコル、アルゴリズム、およびキーの長さをサポートする必要があります

  3. (オプション) ライブラリは旧バージョンとの互換性を保つ目的に限り、古いセキュリティ プロトコルまたはアルゴリズムをサポートできる必要があります

"ネイティブ コード"

  • 暗号化プリミティブ: ご使用のリリースが WindowsまたはWindows Phone である場合、可能であれば CNGを使用します。 それ以外の場合は、CryptoAPI (CAPI とも呼ばれ、Windows Vista 以降では Windows でレガシ コンポーネントとしてサポートされています)を使用します。

  • SSL/TLS/DTLS: WinINetWinHTTPSchannelIXMLHTTPRequest2または IXMLHTTPRequest3

    • WinHTTP アプリは、TLS 1.2をサポートするために WinHttpSetOption使用して構築する必要があります
  • コード署名の検証: WinVerifyTrust は、Windows プラットフォームでコード署名を検証するためにサポートされている API です。

  • 証明書の検証 (コード署名または SSL、TLS、DTLSの制限付き証明書の検証で使用されたもの): CAPI2 API。たとえば、CertGetCertificateChain および CertVerifyCertificateChainPolicy

"マネージド コード"

  • 暗号化プリミティブ: System.Security.Cryptography 名前空間で定義されている APIを使用します。CNG クラスが優先されます。

  • 利用可能な最新バージョンの .Net Frameworkを使用します。 少なくとも .Net Framework バージョン 4.6 である必要があります。 古いバージョンが必要な場合は、該当するアプリケーションに対して TLS 1.2を有効にする "SchUseStrongCrypto" レジストリ キーが設定されていることを確認します。

  • 証明書の検証: System.Security.Cryptography.X509Certificates 名前空間で定義されている APIを使用します。

  • SSL/TLS/DTLS: System.Net 名前空間で定義されている APIを使用します (たとえば、HttpWebRequest)

キー派生関数

キーの派生は、共有シークレットまたは既存の暗号化キーから暗号化キー マテリアルを派生させるプロセスです。 製品では、推奨されるキー派生関数を使用する必要があります。 ユーザーが選択したパスワード、または認証システムでの保管のためのハッシュ パスワードからのキーの派生は、このガイダンスで説明されていない特殊なケースです。開発者は専門家に相談する必要があります。

次の標準では、使用が推奨される KDF 関数が指定されています。

  • NIST SP 800-108: "擬似乱数関数を使用したキーの派生に関する推奨事項"。 特に、HMACを疑似乱数関数として持つカウンター モードの KDF

  • NIST SP 800-56A (リビジョン 2): "離散対数暗号を使用したペアワイズ キー確立スキームの推奨事項"。 特に、セクション 5.8.1の "単一ステップのキー派生関数"をお勧めします。

既存のキーからキーを派生させるには、次のいずれかのアルゴリズムを使用して、BCryptKeyDerivation APIを使用します。

  • BCRYPT_SP800108_CTR_HMAC_ALGORITHM

  • BCRYPT_SP80056A_CONCAT_ALGORITHM

共有シークレット (キーの承諾の出力) からキーを派生させるには、次のいずれかのアルゴリズムを使用して BCryptDeriveKey APIを使用します。

  • BCRYPT_KDF_SP80056A_CONCAT

  • BCRYPT_KDF_HMAC

証明書の検証

SSL、TLS、または DTLSを使用する製品は、接続先エンティティの X.509 証明書を完全に検証する必要があります。 これには、以下の証明書の検証が含まれます。

  • ドメイン名

  • 有効期間 (開始日と有効期限)。

  • 失効状態。

  • 使用状況 ("サーバー認証" (サーバーの場合)、"クライアント認証" (クライアントの場合) など)。

  • 信頼チェーン。 プラットフォームによって信頼されている、または管理者によって明示的に構成されているルート証明機関 (CA) に、証明書がチェーンされている必要があります。

これらの検証テストのいずれかが失敗した場合、製品はエンティティとの接続を終了する必要があります。

"自己署名" 証明書を信頼するクライアント (たとえば、既定の構成で Exchange サーバー に接続しているメール クライアント) は、証明書の検証チェックを無視する場合があります。 ただし、自己署名証明書では本質的に、信頼の伝達、失効のサポート、およびキーの更新のサポートは行われません。 自己署名証明書は、信頼できる別のソース (認証され整合性が保護されたトランスポート経由で証明書を提供する信頼されたエンティティなど) から取得した場合のみ信頼する必要があります。

暗号化ハッシュ関数

製品では、SHA-2 ファミリのハッシュ アルゴリズム (SHA256、SHA384、SHA512)を使用する必要があります。 セキュリティ上の目的で暗号化ハッシュを切り捨てる場合、128 ビット未満に切り捨てることは推奨されていません。

MAC、HMAC、キー付きハッシュ アルゴリズム

メッセージ認証コード (MAC) はメッセージに添付される情報の一部です。MAC により、メッセージの受信者は、秘密キーを使用して送信元の信頼性とメッセージの整合性を確認することが可能になります。

基になるすべてのハッシュ アルゴリズムまたは対称暗号化アルゴリズムも使用が推奨されていれば、ハッシュ ベースの MAC (HMAC) またはブロック暗号ベースの MACの使用が推奨されます。現時点では、これには HMAC-SHA2 関数 (HMAC-SHA256、HMAC-SHA384、HMAC-SHA512) が含まれます。

HMACを128 ビット未満に切り捨てることは推奨されていません。

設計および運用面の考慮事項

  • 必要に応じて暗号化キーを交換するメカニズムを提供する必要があります。 キーは、アクティブな有効期間が終了するか、暗号化キーが侵害されたときに交換する必要があります。 証明書を更新するときは、常に新しいキーを使用して証明書を更新する必要があります。

  • 暗号化アルゴリズムを使用してデータを保護する製品には、将来のさまざまなアルゴリズムへの移行をサポートするために、そのコンテンツと共に十分なメタデータを含める必要があります。 これには使用されるアルゴリズム、キーのサイズ、初期化ベクトル、パディング モードなどがあります。

  • 可能な場合は、製品ではプロトコルを再実装するのではなく、確立された、プラットフォームで提供される暗号化プロトコルを使用する必要があります。 これには署名形式も含まれます (たとえば標準の既存の形式を使用します)。

  • 対称ストリーム暗号 (RC4 など) は使用しないでください。 製品では、対称ストリーム暗号ではなく、ブロック暗号を使用する必要があります。具体的には、キー長が 128 ビット以上の AESを使用します。

  • 暗号化操作の失敗をエンドユーザーに報告しないでください。 リモートの呼び出し元 (Web クライアントや、クライアントとサーバーのシナリオでのクライアントなど) にエラーを返す場合は、一般的なエラー メッセージのみを使用してください。

    • 範囲外または無効な長さのエラーを直接報告するなど、不要な情報を提供することは避けてください。 詳細ログが有効になっている場合に限り、サーバー側でのみ詳細エラーをログに記録します。
  • 次のものを含む設計については、追加のセキュリティ レビューを強くお勧めします。

    • セキュリティに重点を置いた新しいプロトコル (認証または認可プロトコルなど)

    • 新規あるいは標準外の方法の暗号化を使用する新しいプロトコル。たとえば次のような考慮事項があります。

      • 当該プロトコルを実装する製品は、プロトコル実装の一部として任意の暗号化の API またはメソッドを呼び出しますか。

      • 当該プロトコルは、認証または認可に使用される他のプロトコルに依存していますか。

      • 当該プロトコルは、キーなどの暗号化要素の保管形式を定義しますか。

  • 運用環境では、自己署名証明書を使用しないことをお勧めします。 未加工の暗号化キーを使用するなど、自己署名証明書を使用しても、信頼の決定を行うための根拠がユーザーや管理者に本質的に提供されません。

    • これに対して、信頼された証明機関をルートとする証明書を使用すると、関連付けられている秘密キーに依存する根拠が明確になり、セキュリティ障害が発生した場合に失効と更新を行うことができます。

保管する前の機密データの暗号化

DPAPI/DPAPI-NG

システムの再起動後も永続化する必要があるデータの場合:

  • CryptProtectData

  • CryptUnprotectData

  • NCryptProtectSecret (Windows 8 CNG DPAPI)

システムの再起動後は永続化する必要がないデータの場合:

  • CryptProtectMemory

  • CryptUnprotectMemory

永続化する必要があり、複数のドメイン アカウントとコンピューターによってアクセスされる必要があるデータの場合:

SQL Server TDE

SQL Server Transparent Data Encryption (TDE)を使用して、機密データを保護することができます。

SDLの暗号アルゴリズムとキーの強度の要件を満たす TDE データベース暗号化キー (DEK)を使用する必要があります。 現時点では、AES_128、AES_192、および AES_256のみが推奨され、TRIPLE_DES_3KEY は推奨されません。

SQL TDEを使用する上で留意すべき重要な考慮事項がいくつかあります。

  • SQL Server は、TDE が有効になっている場合でも、FILESTREAM データの暗号化をサポートしていません。

  • TDE では、データベースとの間で転送中のデータの暗号化は自動的には提供されません。また、SQL Server データベースへの暗号化接続を有効にする必要もあります。 暗号化された接続を有効にする方法については、「データベース エンジンへの暗号化接続の有効化」 (SQL Server 構成マネージャー)を参照してください。

  • TDE で保護されたデータベースを別の SQL Server インスタンスに移動する場合は、TDE データ暗号化キー (DEK)を保護する証明書も移動して、移動先の SQL Server インスタンスのマスター データベースにインストールする必要があります。 詳細については、TechNetの記事「別の SQL Server への TDE で保護されたデータベースの移動」を参照してください。

"資格情報の管理"

Windows Credential Manager APIまたはMicrosoft Azure KeyVaultを使用して、パスワードと資格情報のデータを保護します。

"Windows ストア アプリ"

Windows.Security.Cryptography および Windows.Security.Cryptography.DataProtection 名前空間のクラスを使用して、シークレットと機密データを保護します。

  • ProtectAsync

  • ProtectStreamAsync

  • UnprotectAsync

  • UnprotectStreamAsync

Windows.Security.Credentials 名前空間のクラスを使用して、パスワードおよび資格情報のデータを保護します。

.NET

システムの再起動後も永続化する必要があるデータの場合:

  • ProtectedData.Protect

  • ProtectedData.Unprotect

システムの再起動後は永続化する必要がないデータの場合:

  • ProtectedMemory.Protect

  • ProtectedMemory.Unprotect

構成ファイルの場合

RSAProtectedConfigurationProviderまたはDPAPIProtectedConfigurationProviderのいずれかを使用して、それぞれ RSA 暗号化または DPAPIのいずれかを使用することによって構成を保護します。

RSAProtectedConfigurationProvider は、クラスター内の複数のコンピューターで使用できます。 詳細については、「保護された構成を使用した構成情報の暗号化」を参照してください。