NCryptDeriveKeyFn
コールバックシグネチャ
HRESULT NCryptDeriveKeyFn(
NCRYPT_PROV_HANDLE hProvider,
NCRYPT_SECRET_HANDLE hSharedSecret,
LPWSTR pwszKDF,
BCryptBufferDesc* pParameterList,
BYTE* pbDerivedKey,
DWORD cbDerivedKey,
DWORD* pcbResult,
DWORD dwFlags
);パラメーター
| フィールド | 型 | 説明 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| hProvider | NCRYPT_PROV_HANDLE | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hSharedSecret | NCRYPT_SECRET_HANDLE | 鍵の作成元となるシークレットのハンドルです。現在、このハンドルは NCryptSecretAgreement 関数から取得します。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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 の one-step KDF (セクション 4.1) としても知られています。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます (または含める必要があります)。必須か省略可能かは「必須/省略可能」列を参照してください。すべてのパラメーター値は、不透明なバイト配列として扱われます。
KDF の呼び出しは、次の疑似コードのように行われます。
Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: この値はサポートされません。 BCRYPT_KDF_RAW_SECRET (L"TRUNCATE")生のシークレットを、変更を加えずにリトル エンディアン表現で返します。 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 ベースの Extract-and-Expand KDF) 関数を使用します。 HKDF では、次のどちらから鍵を派生させるかが区別されます。
第 1 段階では、シークレット ハンドルから疑似乱数鍵 (PRK) を「Extract (抽出)」します。この段階は、シークレット ハンドルに対して BCRYPT_HKDF_HASH_ALGORITHM を指定して BCryptSetProperty を呼び出し、HKDF の HMAC 計算で使用するハッシュ アルゴリズムを設定することで行います。 続いて、次のいずれかを指定して BCryptSetProperty を 2 回目に呼び出します。
第 2 段階では、PRK を出力の派生鍵へと「Expand (拡張)」します。この段階は、確定済みのシークレット ハンドルに対して BCryptDeriveKey を呼び出すことで行います。 pParameterList パラメーターで指定するパラメーターには、次のパラメーターを含めることができます (または含める必要があります)。必須か省略可能かは「必須/省略可能」列を参照してください。すべてのパラメーター値は、不透明なバイト配列として扱われます。
KDF の呼び出しは、次の疑似コードのように行われます。
Windows 10: HKDF のサポートが開始されました。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pParameterList | BCryptBufferDesc* | KDF パラメーターを格納した NCryptBufferDesc 構造体のアドレスです。このパラメーターは省略可能で、不要な場合は NULL を指定できます。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pbDerivedKey | BYTE* | 鍵を受け取るバッファーのアドレスです。cbDerivedKey パラメーターには、このバッファーのサイズを指定します。このパラメーターが NULL の場合、この関数は必要なサイズをバイト単位で、pcbResult パラメーターが指す DWORD に格納します。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cbDerivedKey | DWORD | pbDerivedKey バッファーのサイズ (バイト単位) です。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pcbResult | DWORD* | pbDerivedKey バッファーにコピーされたバイト数を受け取る DWORD へのポインターです。pbDerivedKey パラメーターが NULL の場合、この関数は必要なサイズをバイト単位で、このパラメーターが指す DWORD に格納します。 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dwFlags | DWORD | この関数の動作を変更するフラグのセットです。 ゼロ、または次の値を指定できます。
|
公式ドキュメント
NCryptDeriveKey 関数は、NCRYPT_SECRET_HANDLE から鍵を派生させます。この関数は、永続化されたシークレット アグリーメント鍵を使用するシークレット アグリーメント手続きの一部として使用することを想定しています。
永続化されたシークレットを使用して鍵素材を派生させるには、代わりに NCryptKeyDerivation 関数を使用してください。
戻り値
関数の成功または失敗を示すステータス コードを返します。
返される可能性のあるコードには、次のものが含まれます (これらに限定されません)。
| 戻り値 | 説明 |
|---|---|
| ERROR_SUCCESS | 関数は成功しました。 |
| NTE_INVALID_HANDLE | hSharedSecret パラメーターのハンドルが無効です。 |
| NTE_INVALID_PARAMETER | 1 つ以上のパラメーターが無効です。 |
解説(Remarks)
pParameterList パラメーターに指定する NCryptBufferDesc 構造体には、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 関数のほとんどはビッグ エンディアンでエンコードされた入力を受け取るため、生のシークレットをそれらの関数で使用する際は、この点に注意することが重要です。
サービスは、StartService 関数からこの関数を呼び出してはいけません。サービスが StartService 関数からこの関数を呼び出すと、デッドロックが発生し、サービスが応答しなくなる可能性があります。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)