BCryptDeriveKeyFn
コールバックシグネチャ
NTSTATUS BCryptDeriveKeyFn(
BCRYPT_SECRET_HANDLE hSharedSecret,
LPWSTR pwszKDF,
BCryptBufferDesc* pParameterList,
BYTE* pbDerivedKey,
DWORD cbDerivedKey,
DWORD* pcbResult,
DWORD dwFlags
);パラメーター
| フィールド | 型 | 説明 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hSharedSecret | BCRYPT_SECRET_HANDLE | キーの作成元となるシークレットのハンドルです。このハンドルは BCryptSecretAgreement 関数から取得します。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pwszKDF | LPWSTR | キーの派生に使用する キー派生関数 (KDF) を識別する、null で終わる Unicode 文字列へのポインターです。次のいずれかの文字列を指定できます。 BCRYPT_KDF_HASH (L"HASH")ハッシュ キー派生関数を使用します。 cbDerivedKey パラメーターが派生キーのサイズより小さい場合、この関数は指定されたバイト数だけを pbDerivedKey バッファーにコピーします。これは結果として得られるキーのセキュリティ強度を大幅に低下させる可能性があるため、通常は望ましくありません。 cbDerivedKey パラメーターが派生キーのサイズより大きい場合、この関数はキーを pbDerivedKey バッファーにコピーし、pcbResult が指す変数に実際にコピーされたバイト数を設定します。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます。必須かどうかは「必須または省略可能」列のとおりです。
KDF の呼び出しは、次の擬似コードのように行われます。
BCRYPT_KDF_HMAC (L"HMAC")ハッシュ ベース メッセージ認証コード (HMAC) キー派生関数を使用します。 cbDerivedKey パラメーターが派生キーのサイズより小さい場合、この関数は指定されたバイト数だけを pbDerivedKey バッファーにコピーします。これは結果として得られるキーのセキュリティ強度を大幅に低下させる可能性があるため、通常は望ましくありません。 cbDerivedKey パラメーターが派生キーのサイズより大きい場合、この関数はキーを pbDerivedKey バッファーにコピーし、pcbResult が指す変数に実際にコピーされたバイト数を設定します。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます。必須かどうかは「必須または省略可能」列のとおりです。
KDF の呼び出しは、次の擬似コードのように行われます。
BCRYPT_KDF_TLS_PRF (L"TLS_PRF")トランスポート層セキュリティ (TLS) の 疑似乱数関数 (PRF) キー派生関数を使用します。派生キーのサイズは常に 48 バイトであるため、cbDerivedKey パラメーターには 48 を指定する必要があります。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます。必須かどうかは「必須または省略可能」列のとおりです。
KDF の呼び出しは、次の擬似コードのように行われます。
BCRYPT_KDF_SP80056A_CONCAT (L"SP800_56A_CONCAT")SP800-56A キー派生関数を使用します。これは SP800-56C rev2 のワンステップ KDF としても知られています。 この KDF は承認されたハッシュ関数をパラメーターとして受け取りますが、この API はハッシュ関数を内部で選択し、ハッシュ アルゴリズムのセキュリティ強度を、シークレット ハンドルの生成に使用されたアルゴリズムに合わせます (たとえば ECDH P-256 では SHA256、ECDH P-384 では SHA384 を使用します)。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます。必須かどうかは「必須または省略可能」列のとおりです。パラメーターの値はすべて、不透明なバイト配列として扱われます。
KDF の呼び出しは、次の擬似コードのように行われます。
Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: この値はサポートされていません。 BCRYPT_KDF_RAW_SECRET (L"TRUNCATE")生のシークレットを何も変更せずに、リトル エンディアン表現で返します。このオプションの使用は通常は望ましくありませんが、サポートされていない KDF と相互運用する必要がある場合には必要になることがあります。 cbDerivedKey パラメーターが派生キーのサイズより小さい場合、この関数は指定されたバイト数だけを pbDerivedKey バッファーにコピーします。これは結果として得られるキーのセキュリティ強度を大幅に低下させる可能性があるため、通常は望ましくありません。 cbDerivedKey パラメーターが派生キーのサイズより大きい場合、この関数はキーを pbDerivedKey バッファーにコピーし、pcbResult が指す変数に実際にコピーされたバイト数を設定します。 Windows 8、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: この値はサポートされていません。 BCRYPT_KDF_HKDF (L"HKDF")RFC 5869 の HKDF (HMAC ベースの抽出および拡張 KDF) 関数を使用します。 HKDF では、次のどちらからキーを派生させるかが区別されます。
第 1 段階では、シークレット ハンドルから擬似乱数キー (PRK) を「抽出」します。この段階は、シークレット ハンドルに対して BCRYPT_HKDF_HASH_ALGORITHM を指定して BCryptSetProperty を呼び出し、HKDF の HMAC 計算で使用するハッシュ アルゴリズムを設定することで行います。 続いて、次のいずれかを指定して BCryptSetProperty をもう一度呼び出します。
第 2 段階では、PRK を出力となる派生キーへ「拡張」します。この段階は、確定済みのシークレット ハンドルに対して BCryptDeriveKey を呼び出すことで行います。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます。必須かどうかは「必須または省略可能」列のとおりです。パラメーターの値はすべて、不透明なバイト配列として扱われます。
KDF の呼び出しは、次の擬似コードのように行われます。
Windows 10: HKDF のサポートが開始されました。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pParameterList | BCryptBufferDesc* | KDF のパラメーターを格納した BCryptBufferDesc 構造体のアドレスです。このパラメーターは省略可能で、不要な場合は NULL を指定できます。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pbDerivedKey | BYTE* | キーを受け取るバッファーのアドレスです。cbDerivedKey パラメーターには、このバッファーのサイズを指定します。このパラメーターが NULL の場合、この関数は必要なサイズ (バイト単位) を、pcbResult パラメーターが指す ULONG に格納します。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cbDerivedKey | DWORD | pbDerivedKey バッファーのサイズ (バイト単位) です。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pcbResult | DWORD* | pbDerivedKey バッファーにコピーされたバイト数を受け取る ULONG へのポインターです。pbDerivedKey パラメーターが NULL の場合、この関数は必要なサイズ (バイト単位) を、このパラメーターが指す ULONG に格納します。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dwFlags | DWORD | この関数の動作を変更するフラグのセットです。 0 または次の値を指定できます。
|
公式ドキュメント
BCryptDeriveKey 関数は、BCRYPT_SECRET_HANDLE からキーを派生させます。これは通常、シークレット アグリーメント (秘密合意) 手順の一部として行われます。
呼び出し元が直接指定したシークレットからキーを派生させる場合は、BCryptKeyDerivation を参照してください。
戻り値
関数の成功または失敗を示すステータス コードを返します。
返される可能性のあるコードには、次のものがあります (これらに限りません)。
| 戻り値 | 説明 |
|---|---|
| STATUS_SUCCESS | 関数は成功しました。 |
| STATUS_INTERNAL_ERROR | 内部エラーが発生しました。 |
| STATUS_INVALID_HANDLE | hSharedSecret パラメーターのハンドルが無効です。 |
| STATUS_INVALID_PARAMETER | 1 つ以上のパラメーターが無効です。 |
解説(Remarks)
pParameterList パラメーターに指定する BCryptBufferDesc 構造体には、KDF_SECRET_PREPEND および KDF_SECRET_APPEND パラメーターを複数含めることができます。これらのパラメーターが複数指定された場合、KDF が呼び出される前に、配列に格納されている順序でパラメーターの値が連結されます。たとえば、次のパラメーター値が指定されているとします。
BYTE abValue0[] = {0x01};
BYTE abValue1[] = {0x04, 0x05};
BYTE abValue2[] = {0x10, 0x11, 0x12};
BYTE abValue3[] = {0x20, 0x21, 0x22, 0x23};
Parameter[0].type = KDF_SECRET_APPEND
Parameter[0].value = abValue0;
Parameter[0].length = sizeof (abValue0);
Parameter[1].type = KDF_SECRET_PREPEND
Parameter[1].value = abValue1;
Parameter[1].length = sizeof (abValue1);
Parameter[2].type = KDF_SECRET_APPEND
Parameter[2].value = abValue2;
Parameter[2].length = sizeof (abValue2);
Parameter[3].type = KDF_SECRET_PREPEND
Parameter[3].value = abValue3;
Parameter[3].length = sizeof (abValue3);
上記のパラメーター値が指定された場合、実際に KDF へ渡される連結後の値は次のようになります。
Type: KDF_SECRET_PREPEND
Value: {0x04, 0x05, 0x20, 0x21, 0x22, 0x23}, length 6
Type: KDF_SECRET_APPEND
Value: {0x01, 0x10, 0x11, 0x12}, length 4
pwszKDF パラメーターに BCRYPT_KDF_RAW_SECRET を設定した場合、返されるシークレットは (他の pwszKDF の値とは異なり) リトル エンディアン形式でエンコードされます。CNG の他の関数はほとんどがビッグ エンディアンでエンコードされた入力を受け取るため、生のシークレットをそれらの関数で使用する際にはこの点に注意してください。
サポートされているアルゴリズム プロバイダーを使用する場合、BCryptDeriveKey はユーザー モードとカーネル モードのどちらからでも呼び出せます。カーネル モードの呼び出し元は、PASSIVE_LEVEL IRQL と DISPATCH_LEVEL IRQL のどちらでも実行できます。現在の IRQL レベルが DISPATCH_LEVEL の場合、hSharedSecret パラメーターに渡すハンドルは非ページ (またはロックされた) メモリ上に存在し、BCRYPT_PROV_DISPATCH フラグを使用して開かれたプロバイダーが返したアルゴリズム ハンドルから派生したものでなければなりません。
この関数をカーネル モードで呼び出すには、Driver Development Kit (DDK) に含まれる Cng.lib を使用します。Windows Server 2008 および Windows Vista: この関数をカーネル モードで呼び出すには、Ksecdd.lib を使用します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)