Функция CryptDeriveKey (wincrypt.h)

Важно Этот API является устаревшим. Новое и существующее программное обеспечение должно начать использовать API-интерфейсы шифрования следующего поколения. Корпорация Майкрософт может удалить этот API в будущих выпусках.
 
Функция CryptDeriveKey создает криптографические ключи сеанса , производные от базового значения данных. Эта функция гарантирует, что при использовании одного и того же поставщика служб шифрования (CSP) и алгоритмов ключи, созданные на основе одних и того же базовых данных, будут идентичны. Базовые данные могут быть паролем или любыми другими данными пользователя.

Эта функция аналогична функции CryptGenKey, за исключением того, что созданные ключи сеанса являются производными от базовых данных, а не случайными. CryptDeriveKey можно использовать только для создания ключей сеанса. Он не может создавать пары открытого и закрытого ключей.

Дескриптор сеансового ключа возвращается в параметре phKey . Этот дескриптор можно использовать с любой функцией CryptoAPI, требующей дескриптора ключа.

Синтаксис

BOOL CryptDeriveKey(
  [in]      HCRYPTPROV hProv,
  [in]      ALG_ID     Algid,
  [in]      HCRYPTHASH hBaseData,
  [in]      DWORD      dwFlags,
  [in, out] HCRYPTKEY  *phKey
);

Параметры

[in] hProv

Дескриптор HCRYPTPROV CSP, созданный вызовом CryptAcquireContext.

[in] Algid

Структура ALG_ID , идентифицирующая алгоритм симметричного шифрования , для которого создается ключ. Алгоритмы, доступные для каждого поставщика служб CSP, скорее всего, будут отличаться. Дополнительные сведения о том, какой идентификатор алгоритма используется различными поставщиками для ключевых спецификаций AT_KEYEXCHANGE и AT_SIGNATURE, см. в разделе ALG_ID.

Дополнительные сведения о ALG_ID значениях, используемых с базовым поставщиком шифрования Майкрософт, см. в разделе Алгоритмы базового поставщика. Дополнительные сведения о ALG_ID значениях для использования с поставщиком служб шифрования Microsoft Strong или Microsoft Enhanced Cryptographic Provider см. в разделе Алгоритмы расширенного поставщика.

[in] hBaseData

Дескриптор хэш-объекта , которому были предоставлены точные базовые данные.

Чтобы получить этот дескриптор, приложение должно сначала создать хэш-объект с помощью CryptCreateHash, а затем добавить базовые данные в хэш-объект с помощью CryptHashData. Этот процесс подробно описан в разделе Хэши и цифровые подписи.

[in] dwFlags

Указывает тип создаваемого ключа.

Размеры сеансового ключа можно задать при его создании. Размер ключа, представляющий длину модуля ключа в битах, задается с верхними 16 битами этого параметра. Таким образом, при создании 128-разрядного ключа сеанса RC4 значение 0x00800000 объединяется с любым другим предопределенным значением dwFlags с побитовой операцией ИЛИ . Из-за изменения ограничений управления экспортом CSP по умолчанию и длина ключа по умолчанию могут меняться в разных выпусках операционной системы. Важно, чтобы для шифрования и расшифровки использовался один И тот же CSP, а длина ключа была явно задана с помощью параметра dwFlags , чтобы обеспечить взаимодействие на разных платформах операционной системы.

Нижние 16 бит этого параметра могут быть равны нулю, или можно указать один или несколько следующих флагов с помощью побитового оператора ИЛИ для их объединения.

Значение Значение
CRYPT_CREATE_SALT
Как правило, при создании сеансового ключа из хэш-значения остается несколько битов. Например, если хэш-значение равно 128 битам, а ключ сеанса равен 40 битам, останется 88 бит.

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

Если этот флаг не задан, ключу присваивается значение соли, равное нулю.

При экспорте ключей с ненулевыми значениями соли (с помощью CryptExportKey) значение соли также должно быть получено и сохранено в большом двоичном объекте ключа.

CRYPT_EXPORTABLE
Если этот флаг установлен, сеансовый ключ можно передать из CSP в большой двоичный объект ключа с помощью функции CryptExportKey . Так как ключи обычно должны быть экспортируемыми, этот флаг обычно устанавливается.

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

Этот флаг не применяется к парам открытого и закрытого ключей.

CRYPT_NO_SALT
Этот флаг указывает, что для 40-разрядного симметричного ключа не выделяется значение соли. Дополнительные сведения см. в статье Функциональность соляного значения.
CRYPT_UPDATE_KEY
Некоторые поставщики служб конфигурации используют ключи сеанса, производные от нескольких хэш-значений. В этом случае необходимо вызывать CryptDeriveKey несколько раз.

Если этот флаг установлен, новый ключ сеанса не создается. Вместо этого изменяется ключ, указанный параметром phKey . Точное поведение этого флага зависит от типа создаваемого ключа и конкретного используемого CSP.

Поставщики служб шифрования Майкрософт игнорируют этот флаг.

CRYPT_SERVER
1024 (0x400)
Этот флаг используется только с поставщиками Schannel . Если этот флаг установлен, создаваемый ключ является ключом записи на сервере; в противном случае это ключ записи клиента.

[in, out] phKey

Указатель на переменную HCRYPTKEY для получения адреса дескриптора созданного ключа. Завершив использование ключа, отпустите дескриптор, вызвав функцию CryptDeographyKey .

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

Если функция выполняется успешно, функция возвращает ненулевое значение (TRUE).

Если функция завершается сбоем, она возвращает ноль (FALSE). Для получения дополнительных сведений об ошибке вызовите Метод GetLastError.

Коды ошибок, предваряемые "NTE", создаются конкретным поставщиком служб конфигурации. В следующей таблице перечислены некоторые возможные коды ошибок.

Код возврата Описание
ERROR_INVALID_HANDLE
Один из параметров указывает недопустимый дескриптор.
ERROR_INVALID_PARAMETER
Один из параметров содержит недопустимое значение. Чаще всего это недопустимый указатель.
NTE_BAD_ALGID
Параметр Algid указывает алгоритм, который не поддерживается этим поставщиком служб конфигурации.
NTE_BAD_FLAGS
Параметр dwFlags содержит недопустимое значение.
NTE_BAD_HASH
Параметр hBaseData не содержит допустимый дескриптор для хэш-объекта.
NTE_BAD_HASH_STATE
Предпринята попытка добавить данные в хэш-объект, который уже помечен как завершенный.
NTE_BAD_UID
Параметр hProv не содержит допустимый дескриптор контекста.
NTE_FAIL
Сбой функции каким-то непредвиденным образом.
NTE_SILENT_CONTEXT
Поставщику не удалось выполнить действие, так как контекст был получен как автоматический.

Комментарии

При создании ключей для симметричногоблочного шифра ключ по умолчанию настраивается в режиме цепочки блоков шифров (CBC) с вектором инициализации нулевым. Этот режим шифра предоставляет хороший метод по умолчанию для массового шифрования данных. Чтобы изменить эти параметры, используйте функцию CryptSetKeyParam .

Функция CryptDeriveKey завершает хэш. После вызова CryptDeriveKey больше нельзя добавить данные в хэш. Дополнительные вызовы CryptHashData или CryptHashSessionKey завершаются ошибкой . После завершения работы приложения с хэшем необходимо вызвать CryptDeographyHash , чтобы уничтожить хэш-объект.

Чтобы выбрать подходящую длину ключа, рекомендуется использовать следующие методы.

  • Чтобы перечислить алгоритмы, поддерживаемые CSP, и получить максимальную и минимальную длину ключей для каждого алгоритма, вызовите CryptGetProvParam с PP_ENUMALGS_EX.
  • Используйте минимальную и максимальную длину, чтобы выбрать подходящую длину ключа. Не всегда рекомендуется выбирать максимальную длину, так как это может привести к проблемам с производительностью.
  • После выбора нужной длины ключа используйте верхние 16 бит параметра dwFlags , чтобы указать длину ключа.
Пусть n — необходимая длина производного ключа в байтах. Производный ключ — это первые n байтов хэш-значения после завершения вычисления хэша с помощью CryptDeriveKey. Если хэш не входит в семейство SHA-2, а необходимый ключ предназначен для 3DES или AES, ключ выводится следующим образом:
  1. Создайте 64-байтный буфер, повторяя константу 0x36 64 раза. Пусть k — это длина хэш-значения, представленного входным параметром hBaseData. Задайте первые k байтов буфера в результате операции XOR первых k байтов буфера с хэш-значением, представленным входным параметром hBaseData.
  2. Создайте 64-байтный буфер, повторяя константу 0x5C 64 раза. Задайте первые k байтов буфера в результате операции XOR первых k байтов буфера с хэш-значением, представленным входным параметром hBaseData.
  3. Хэшировать результат шага 1 с помощью того же хэш-алгоритма, что и для вычисления хэш-значения, представленного параметром hBaseData .
  4. Хэшировать результат шага 2 с помощью того же хэш-алгоритма, что и для вычисления хэш-значения, представленного параметром hBaseData .
  5. Сцепить результат шага 3 с результатом шага 4.
  6. Используйте первые n байтов результата шага 5 в качестве производного ключа.
Поставщик служб полного шифрования RSA по умолчанию — это поставщик служб шифрования Microsoft RSA Strong. Поставщик служб шифрования по умолчанию Diffie-Hellman подписи DSS — это поставщик служб шифрования microsoft Enhanced DSS Diffie-Hellman. Каждый из этих CSP имеет 128-разрядный симметричный ключ по умолчанию для RC2 и RC4.

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

Поставщик Алгоритмы Минимальная длина ключа Длина ключа по умолчанию Максимальная длина ключа
MS Base RC4 и RC2 40 40 56
MS Base DES 56 56 56
MS Enhanced RC4 и RC2 40 128 128
MS Enhanced DES 56 56 56
MS Enhanced 3DES 112 112 112 112
MS Enhanced 3DES 168 168 168
MS Strong RC4 и RC2 40 128 128
MS Strong DES 56 56 56
MS Strong 3DES 112 112 112 112
MS Strong 3DES 168 168 168
DSS/DH Base RC4 и RC2 40 40 56
DSS/DH Base Cylink MEK 40 40 40
DSS/DH Base DES 56 56 56
DSS/DH Enh RC4 и RC2 40 128 128
DSS/DH Enh Cylink MEK 40 40 40
DSS/DH Enh DES 56 56 56
DSS/DH Enh 3DES 112 112 112 112
DSS/DH Enh 3DES 168 168 168
 

Примеры

Пример использования этой функции см. в разделе Пример программы C: создание ключа сеанса из пароля.

Требования

Требование Значение
Минимальная версия клиента Windows XP [только классические приложения]
Минимальная версия сервера Windows Server 2003 [только классические приложения]
Целевая платформа Windows
Header wincrypt.h
Библиотека Advapi32.lib
DLL Advapi32.dll

См. также раздел

CryptAcquireContext

CryptCreateHash

CryptDeographyHash

CryptDecryptKey

CryptExportKey

CryptGenKey

CryptGetKeyParam

CryptHashData

CryptHashSessionKey

CryptSetKeyParam

Функции создания ключей и обмена