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


Функция NCryptDeriveKey (ncrypt.h)

Функция NCryptDeriveKey является производным ключом от NCRYPT_SECRET_HANDLE. Эта функция предназначена для использования в рамках процедуры секретного соглашения с использованием сохраненных ключей секретного соглашения.

Чтобы получить материал ключа с помощью сохраненного секрета, используйте функцию NCryptKeyDerivation .

Синтаксис

SECURITY_STATUS NCryptDeriveKey(
  [in]            NCRYPT_SECRET_HANDLE hSharedSecret,
  [in]            LPCWSTR              pwszKDF,
  [in, optional]  NCryptBufferDesc     *pParameterList,
  [out, optional] PBYTE                pbDerivedKey,
  [in]            DWORD                cbDerivedKey,
  [out]           DWORD                *pcbResult,
  [in]            ULONG                dwFlags
);

Параметры

[in] hSharedSecret

Секретный дескриптор для создания ключа из. Этот дескриптор в настоящее время получен из функции NCryptSecretAgreement .

[in] pwszKDF

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

BCRYPT_KDF_HASH (L"HASH")

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

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

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

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

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

Параметр Description Обязательно или необязательно
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 (раздел 4.1) с использованием утвержденной хэш-функции, соответствующей алгоритму, используемому для создания секретного дескриптора.

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

Параметр Description Обязательно или необязательно
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")

Возвращает небольшое представление необработанного секрета без каких-либо изменений.

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

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

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

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

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

[in, optional] pParameterList

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

[out, optional] pbDerivedKey

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

[in] cbDerivedKey

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

[out] pcbResult

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

[in] dwFlags

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

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

Ценность Meaning
KDF_USE_SECRET_AS_HMAC_KEY_FLAG Значение в hSharedSecret также будет служить ключом HMAC. Если этот флаг указан, параметр KDF_HMAC_KEY не должен быть включен в набор параметров в параметре pParameterList . Этот флаг используется только функцией производного ключа BCRYPT_KDF_HMAC .

Возвращаемое значение

Возвращает код состояния, указывающий на успешность или сбой функции.

Возможные коды возврата включают в себя, но не ограничиваются следующими.

Возвращаемый код Description
ERROR_SUCCESS Функция была успешной.
NTE_INVALID_HANDLE Дескриптор в параметре hSharedSecret недопустим.
NTE_INVALID_PARAMETER Один или несколько параметров недопустимы.

Замечания

Структура NCryptBufferDesc в параметре 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, так как большинство из них принимают в кодированные входные данные в большом коде.

Служба не должна вызывать эту функцию из функции StartService. Если служба вызывает эту функцию из функции StartService, может произойти взаимоблокировка, а служба может перестать отвечать.

Требования

Требование Ценность
Минимальный поддерживаемый клиент Windows Vista [классические приложения | Приложения UWP]
минимальный поддерживаемый сервер Windows Server 2008 [классические приложения | Приложения UWP]
целевая платформа Виндоус
Header ncrypt.h
Library Ncrypt.lib
DLL Ncrypt.dll

См. также

NCryptBufferDesc

NCryptSecretAgreement