次の方法で共有


BCryptDeriveKey 関数 (bcrypt.h)

BCryptDeriveKey 関数は、BCRYPT_SECRET_HANDLEからキーを派生させます。 これは通常、秘密契約の手順の一部として行われます。

呼び出し元から直接提供されるシークレットからのキーの派生については、 BCryptKeyDerivation を参照してください。

構文

NTSTATUS BCryptDeriveKey(
  [in]            BCRYPT_SECRET_HANDLE hSharedSecret,
  [in]            LPCWSTR              pwszKDF,
  [in, optional]  BCryptBufferDesc     *pParameterList,
  [out, optional] PUCHAR               pbDerivedKey,
  [in]            ULONG                cbDerivedKey,
  [out]           ULONG                *pcbResult,
  [in]            ULONG                dwFlags
);

パラメーター

[in] hSharedSecret

キーを作成するシークレット ハンドル。 このハンドルは 、BCryptSecretAgreement 関数から取得されます。

[in] pwszKDF

キーの派生に使用する キー派生関数 (KDF) を識別する null で終わる Unicode 文字列へのポインター。 次のいずれかの文字列を指定できます。

BCRYPT_KDF_HASH (L"HASH")

ハッシュ キー派生関数を使用します。

cbDerivedKey パラメーターが派生キーのサイズより小さい場合、この関数は指定されたバイト数のみを pbDerivedKey バッファーにコピーします。 これは通常、結果として得られるキーのセキュリティ強度を大幅に低下させる可能性があるため、不適切な方法です。

cbDerivedKey パラメーターが派生キーのサイズより大きい場合、この関数は pbDerivedKey バッファーにキーをコピーし、pcbResult が指す変数をコピーした実際のバイト数に設定します。

pParameterList パラメーターによって識別されるパラメーターは、Required 列または省略可能な列で示されているように、次のパラメーターを含めることができます。または含まれている必要があります。

パラメーター 形容 必須または省略可能
KDF_HASH_ALGORITHM 使用するハッシュ アルゴリズムを識別する null で終わる Unicode 文字列。 CNG アルゴリズム識別子からの標準ハッシュ アルゴリズム識別子の 1 つ、または別の登録済みハッシュ アルゴリズムの識別子を指定できます。

このパラメーターを指定しない場合は、SHA1 ハッシュ アルゴリズムが使用されます。
オプション
KDF_SECRET_PREPEND ハッシュ関数へのメッセージ入力の先頭に追加する値。 詳細については、「解説」を参照してください。 オプション
KDF_SECRET_APPEND ハッシュ関数へのメッセージ入力の末尾に追加する値。 詳細については、「解説」を参照してください。 オプション

KDF の呼び出しは、次の擬似コードに示すように行われます。

KDF-Output = Hash(
    KDF-Prepend + 
    hSharedSecret + 
    KDF-Append)

BCRYPT_KDF_HMAC (L"HMAC")

Hash-Based メッセージ認証コード (HMAC) キー派生関数を使用します。

cbDerivedKey パラメーターが派生キーのサイズより小さい場合、この関数は指定されたバイト数のみを pbDerivedKey バッファーにコピーします。 これは通常、結果として得られるキーのセキュリティ強度を大幅に低下させる可能性があるため、不適切な方法です。

cbDerivedKey パラメーターが派生キーのサイズより大きい場合、この関数は pbDerivedKey バッファーにキーをコピーし、pcbResult が指す変数をコピーした実際のバイト数に設定します。

pParameterList パラメーターによって識別されるパラメーターは、Required 列または省略可能な列で示されているように、次のパラメーターを含めることができます。または含まれている必要があります。

パラメーター 形容 必須または省略可能
KDF_HASH_ALGORITHM 使用するハッシュ アルゴリズムを識別する null で終わる Unicode 文字列。 CNG アルゴリズム識別子からの標準ハッシュ アルゴリズム識別子の 1 つ、または別の登録済みハッシュ アルゴリズムの識別子を指定できます。

このパラメーターを指定しない場合は、SHA1 ハッシュ アルゴリズムが使用されます。
オプション
KDF_HMAC_KEY 擬似ランダム関数 (PRF) に使用するキー。 オプション
KDF_SECRET_PREPEND ハッシュ関数へのメッセージ入力の先頭に追加する値。 詳細については、「解説」を参照してください。 オプション
KDF_SECRET_APPEND ハッシュ関数へのメッセージ入力の末尾に追加する値。 詳細については、「解説」を参照してください。 オプション

KDF の呼び出しは、次の擬似コードに示すように行われます。

KDF-Output = HMAC-Hash(
    KDF_HMAC_KEY,
    KDF-Prepend + 
    hSharedSecret + 
    KDF-Append)

BCRYPT_KDF_TLS_PRF (L"TLS_PRF")

トランスポート層セキュリティ (TLS) 擬似ランダム関数 (PRF) キー派生関数を使用します。 派生キーのサイズは常に 48 バイトであるため、 cbDerivedKey パラメーターは 48 である必要があります。

pParameterList パラメーターによって識別されるパラメーターは、Required 列または省略可能な列で示されているように、次のパラメーターを含めることができます。または含まれている必要があります。

パラメーター 形容 必須または省略可能
KDF_TLS_PRF_LABEL PRF ラベルを含む ANSI 文字列。 必須
KDF_TLS_PRF_SEED PRF シード。 シードの長さは 64 バイトである必要があります。 必須
KDF_TLS_PRF_PROTOCOL PRF アルゴリズムを使用する TLS プロトコル バージョンを指定する DWORD 値。

有効な値は次のとおりです。
SSL2_PROTOCOL_VERSION (0x0002)
SSL3_PROTOCOL_VERSION (0x0300)
TLS1_PROTOCOL_VERSION (0x0301)
TLS1_0_PROTOCOL_VERSION (0x0301)
TLS1_1_PROTOCOL_VERSION (0x0302)
TLS1_2_PROTOCOL_VERSION (0x0303)
DTLS1_0_PROTOCOL_VERSION (0xfeff)

Windows Server 2008 と Windows Vista: TLS1_1_PROTOCOL_VERSION、TLS1_2_PROTOCOL_VERSION、DTLS1_0_PROTOCOL_VERSIONはサポートされていません。

Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista: DTLS1_0_PROTOCOL_VERSIONはサポートされていません。
オプション
KDF_HASH_ALGORITHM TLS 1.2 プロトコル バージョンの PRF の HMAC で使用されるハッシュの CNG アルゴリズム ID。 有効な選択肢は SHA-256 と SHA-384 です。 指定しない場合は、SHA-256 が使用されます。 オプション

KDF の呼び出しは、次の擬似コードに示すように行われます。

KDF-Output = PRF(
    hSharedSecret, 
    KDF_TLS_PRF_LABEL, 
    KDF_TLS_PRF_SEED)

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 パラメーターによって識別されるパラメーターは、Required 列または省略可能な列で示されているように、次のパラメーターを含めることができます。または含まれている必要があります。 すべてのパラメーター値は、不透明なバイト配列として扱われます。

パラメーター 形容 必須または省略可能
KDF_ALGORITHMID SP800-56A キー派生関数の OtherInfo フィールドの AlgorithmID サブフィールドを指定します。 派生キーの目的を示します。 必須
KDF_PARTYUINFO SP800-56A キー派生関数の OtherInfo フィールドの PartyUInfo サブフィールドを指定します。 このフィールドには、イニシエーターが提供するパブリック情報が含まれています。 必須
KDF_PARTYVINFO SP800-56A キー派生関数の OtherInfo フィールドの PartyVInfo サブフィールドを指定します。 このフィールドには、レスポンダーによって提供された公開情報が含まれます。 必須
KDF_SUPPPUBINFO SP800-56A キー派生関数の OtherInfo フィールドの SuppPubInfo サブフィールドを指定します。 このフィールドには、イニシエーターとレスポンダーの両方に既知のパブリック情報が含まれています。 オプション
KDF_SUPPPRIVINFO SP800-56A キー派生関数の OtherInfo フィールドの SuppPrivInfo サブフィールドを指定します。 これには、共有シークレットなど、イニシエーターとレスポンダーの両方に知られている個人情報が含まれています。 オプション

KDF の呼び出しは、次の擬似コードに示すように行われます。

KDF-Output = SP_800-56A_KDF(
    hSharedSecret,
    KDF_ALGORITHMID,
    KDF_PARTYUINFO,
    KDF_PARTYVINFO,
    KDF_SUPPPUBINFO,
    KDF_SUPPPRIVINFO)

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 ベースの Extract-and-Expand KDF) 関数を使用します。

HKDF では、次のいずれかからキーを派生する方法が区別されます。

  1. 秘密契約関数の出力。これは一様にランダムではなく、入力キーマテリアル (IKM) と見なされます。 BCryptDeriveKey のほぼすべてのユーザーには、この形式のシークレット ハンドルがあります。
  2. 一様にランダムなシークレット値。
最初の手順では、シークレット ハンドルから擬似乱数キー (PRK) を "抽出" します。

この手順は、シークレット ハンドルで BCryptSetProperty を呼び出し、 BCRYPT_HKDF_HASH_ALGORITHM を使用して HKDF の HMAC 計算で使用するハッシュ アルゴリズムを設定することによって実行されます。 その後、次のいずれかを使用して BCryptSetProperty を 2 回目に呼び出します。

  1. シークレット ハンドルが IKM を表す場合は、 BCRYPT_HKDF_SALT_AND_FINALIZE を使用してオプションの salt 値を指定し、IKM から PRK を抽出し、シークレット ハンドルを最終処理します。
  2. それ以外の場合は、 BCRYPT_HKDF_PRK_AND_FINALIZE を使用してシークレット値を HKDF PRK に直接変換し、シークレット ハンドルを最終処理します。
2 番目の手順は、PRK を出力派生キーに "展開" することです。

この手順は、最終的なシークレット ハンドルで BCryptDeriveKey を呼び出すことによって実行されます。

pParameterList パラメーターによって識別されるパラメーターは、Required 列または省略可能な列で示されているように、次のパラメーターを含めることができます。または含まれている必要があります。 すべてのパラメーター値は、不透明なバイト配列として扱われます。

パラメーター 形容 必須または省略可能
KDF_HKDF_INFO HKDF 展開ステップの 情報 フィールドを指定します。 省略可能なコンテキストとアプリケーション固有の情報を示します。 オプション

KDF の呼び出しは、次の擬似コードに示すように行われます。

KDF-Output = HKDF-Expand(
    hSharedSecret.PRK,
    info,
    cbDerivedKey)

Windows 10: HKDF のサポートが開始されます。

[in, optional] pParameterList

KDF パラメーターを含む BCryptBufferDesc 構造体のアドレス。 このパラメーターは省略可能であり、必要ない場合は NULL できます。

[out, optional] pbDerivedKey

キーを受け取るバッファーのアドレス。 cbDerivedKey パラメーターには、このバッファーのサイズが含まれています。 このパラメーターがNULL場合、この関数は、pcbResult パラメーターが指す ULONG に必要なサイズ (バイト単位) を配置します。

[in] cbDerivedKey

pbDerivedKey バッファーのサイズ (バイト単位)。

[out] pcbResult

pbDerivedKey バッファーにコピーされたバイト数を受け取る ULONG へのポインター。 pbDerivedKey パラメーターがNULL場合、この関数は、このパラメーターが指す ULONG に必要なサイズ (バイト単位) を配置します。

[in] dwFlags

この関数の動作を変更するフラグのセット。

0 または次の値を指定できます。

価値 意味
KDF_USE_SECRET_AS_HMAC_KEY_FLAG hSharedSecret の値は、HMAC キーとしても機能します。 このフラグを指定した場合、 KDF_HMAC_KEY パラメーターは pParameterList パラメーター内のパラメーターのセットに含めないようにする必要があります。 このフラグは、 BCRYPT_KDF_HMAC キー派生関数でのみ使用されます。

戻り値

関数の成功または失敗を示す状態コードを返します。

可能なリターン コードは次のとおりですが、これらに限定されません。

リターン コード 形容
STATUS_SUCCESS 関数が成功しました。
STATUS_INTERNAL_ERROR 内部エラーが発生しました。
STATUS_INVALID_HANDLE hSharedSecret パラメーターのハンドルが無効です。
STATUS_INVALID_PARAMETER 1 つ以上のパラメーターが無効です。

備考

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 フラグを使用して開かれたプロバイダーによって返されるアルゴリズム ハンドルから派生する必要があります。

カーネル モードでこの関数を呼び出すには、ドライバー開発キット (DDK) の一部である Cng.libを使用します。 Windows Server 2008 と Windows Vista: カーネル モードでこの関数を呼び出すには、Ksecdd.lib を使用します。

必要条件

要件 価値
サポートされる最小クライアント Windows Vista [デスクトップ アプリ |UWP アプリ]
サポートされる最小サーバー Windows Server 2008 [デスクトップ アプリ |UWP アプリ]
ターゲット プラットフォーム ウィンドウズ
Header bcrypt.h
Library Bcrypt.lib
DLL Bcrypt.dll

関連項目

BCryptBufferDesc

BCryptSecretAgreement