Поделиться через


Функция 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

Указатель на строку Юникода, завершающую значение NULL, которая идентифицирует функцию производных ключей (KDF), используемую для получения ключа. Это может быть одна из следующих строк.

BCRYPT_KDF_HASH (L"HASH")

Используйте функцию производного ключа хэша.

Если параметр cbDerivedKey меньше размера производного ключа, эта функция будет копировать только указанное число байтов в буфер pbDerivedKey . Обычно это плохая практика, так как она может значительно снизить уровень безопасности результирующего ключа.

Если параметр cbDerivedKey больше размера производного ключа, эта функция будет копировать ключ в буфер pbDerivedKey и задать переменную, на которую указывает pcbResult , фактическое число скопированных байтов.

Параметры, определяемые параметром pParameterList , могут или должны содержать следующие параметры, как указано в столбце "Обязательный" или "Необязательный".

Параметр Описание Обязательный или необязательный
KDF_HASH_ALGORITHM Строка Юникода, завершающаяся значением NULL, идентифицирующая используемый хэш-алгоритм. Это может быть один из стандартных идентификаторов хэш-алгоритма из идентификаторов алгоритма CNG или идентификатор другого зарегистрированного хэш-алгоритма.

Если этот параметр не указан, используется хэш-алгоритм 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 , могут или должны содержать следующие параметры, как указано в столбце "Обязательный" или "Необязательный".

Параметр Описание Обязательный или необязательный
KDF_HASH_ALGORITHM Строка Юникода, завершающаяся значением NULL, идентифицирующая используемый хэш-алгоритм. Это может быть один из стандартных идентификаторов хэш-алгоритма из идентификаторов алгоритма CNG или идентификатор другого зарегистрированного хэш-алгоритма.

Если этот параметр не указан, используется хэш-алгоритм 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 , могут или должны содержать следующие параметры, как указано в столбце "Обязательный" или "Необязательный".

Параметр Описание Обязательный или необязательный
KDF_TLS_PRF_LABEL Строка ANSI, содержащая метку PRF. Обязательно
KDF_TLS_PRF_SEED Начальное значение PRF. Начальное значение должно иметь длину 64 байтов. Обязательно
KDF_TLS_PRF_PROTOCOL Значение DWORD , указывающее версию протокола TLS, алгоритм PRF которой используется.

Допустимые значения:
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 Идентификатор алгоритма CNG хэша, используемого с HMAC в PRF, для версии протокола TLS 1.2. Допустимые варианты: 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 , могут или должны содержать следующие параметры, как указано в столбце "Обязательный" или "Необязательный". Все значения параметров обрабатываются как непрозрачные массивы байтов.

Параметр Описание Обязательный или необязательный
KDF_ALGORITHMID Задает подфилд AlgorithmID поля OtherInfo в функции генерации ключей SP800-56A. Указывает предназначенную цель производного ключа. Обязательно
KDF_PARTYUINFO Указывает подфилд PartyUInfo поля OtherInfo в функции извлечения ключей SP800-56A. Поле содержит общедоступную информацию, предоставленную инициатором. Обязательно
KDF_PARTYVINFO Указывает подфилд PartyVInfo поля OtherInfo в функции извлечения ключей SP800-56A. Поле содержит общедоступную информацию, предоставленную ответчиком. Обязательно
KDF_SUPPPUBINFO Указывает подфилд SuppPubInfo поля OtherInfo в функции извлечения ключей SP800-56A. Поле содержит общедоступную информацию, известную как инициатору, так и ответчику. Необязательно
KDF_SUPPPRIVINFO Задает подфилд SuppPrivInfo поля OtherInfo в функции извлечения ключей SP800-56A. Он содержит частную информацию, известную как инициатору, так и ответчику, например общему секрету. Необязательно

Вызов 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")

Используйте функцию HKDF (извлечение и развертывание KDF на основе HMAC) из RFC 5869.

В HKDF различается между производным ключом от одного из следующих элементов:

  1. Выходные данные функции секретного соглашения, которая не является единообразной случайной, и считается входным материалом ключей (IKM). Почти все пользователи BCryptDeriveKey будут иметь секретный дескриптор этой формы.
  2. Однородное случайное значение секрета.
Первым шагом является извлечение псевдорандомного ключа (PRK) из дескриптора секрета.

Этот шаг выполняется путем вызова BCryptSetProperty на дескриптор секрета с BCRYPT_HKDF_HASH_ALGORITHM , чтобы задать хэш-алгоритм для использования в вычислениях HMAC в HKDF. За этим следует второй вызов BCryptSetProperty с одним из следующих вызовов:

  1. Если секретный дескриптор представляет IKM, используйте BCRYPT_HKDF_SALT_AND_FINALIZE , чтобы предоставить необязательное значение соли и извлечь PRK из IKM и завершить дескриптор секрета.
  2. В противном случае используйте BCRYPT_HKDF_PRK_AND_FINALIZE для непосредственного преобразования значения секрета в PRK HKDF и завершения дескриптора секрета.
Второй шаг — развернуть PRK в выходной производный ключ.

Этот шаг выполняется путем вызова BCryptDeriveKey в завершенном дескрипторе секрета.

Параметры, определяемые параметром pParameterList , могут или должны содержать следующие параметры, как указано в столбце "Обязательный" или "Необязательный". Все значения параметров обрабатываются как непрозрачные массивы байтов.

Параметр Описание Обязательный или необязательный
KDF_HKDF_INFO Указывает поле сведений на шаге развертывания HKDF. Указывает необязательный контекст и сведения о конкретном приложении. Необязательно

Вызов KDF выполняется, как показано в следующем псевдокоде.

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

Windows 10: Начинается поддержка HKDF.

[in, optional] pParameterList

Адрес структуры BCryptBufferDesc , содержащей параметры KDF. Этот параметр является необязательным и может быть NULL , если он не нужен.

[out, optional] pbDerivedKey

Адрес буфера, получающего ключ. Параметр cbDerivedKey содержит размер этого буфера. Если этот параметр задан NULL, эта функция будет размещать требуемый размер в байтах в ULONG , на который указывает параметр pcbResult .

[in] cbDerivedKey

Размер в байтах буфера pbDerivedKey .

[out] pcbResult

Указатель на ULONG , получающий количество байтов, скопированных в буфер pbDerivedKey . Если параметр pbDerivedKey имеет NULLзначение, эта функция будет размещать требуемый размер в байтах в ULONG , на который указывает этот параметр.

[in] dwFlags

Набор флагов, изменяющих поведение этой функции.

Это может быть ноль или следующее значение:

Ценность Значение
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 Один или несколько параметров недопустимы.

Замечания

Структура BCryptBufferDesc в параметре pParameterList может содержать несколько параметров 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_LEVELIRQL или DISPATCH_LEVEL IRQL. Если текущий уровень IRQL DISPATCH_LEVEL, дескриптор, предоставленный в параметре hSharedSecret , должен находиться в непакованном (или заблокированном) памяти и должен быть производным от дескриптора алгоритма, возвращенного поставщиком, который был открыт с помощью флага BCRYPT_PROV_DISPATCH .

Чтобы вызвать эту функцию в режиме ядра, используйте Cng.libпакет средств разработки драйверов (DDK). 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