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

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

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

Синтаксис

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

Параметры

[in] hProv

Дескриптор поставщика служб шифрования (CSP), созданного вызовом CryptAcquireContext.

[in] Algid

Значение ALG_ID , определяющее алгоритм, для которого создается ключ. Значения этого параметра зависят от используемого CSP.

ALG_ID значения для использования с базовым поставщиком шифрования Майкрософт см. в разделе Алгоритмы базового поставщика.

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

Для Diffie-Hellman CSP используйте одно из следующих значений.

Значение Значение
CALG_DH_EPHEM
Задает ключ "Эфемерный" Diffie-Hellman.
CALG_DH_SF
Указывает ключ Diffie-Hellman "Store and Forward".
 

Помимо создания ключей сеанса для симметричного алгоритма, эта функция также может создавать пары открытого и закрытого ключей. Каждый клиент CryptoAPI обычно имеет две пары открытого и закрытого ключей. Чтобы создать одну из этих пар ключей, задайте для параметра Algid одно из следующих значений.

Значение Значение
AT_KEYEXCHANGE
обмена ключами;
AT_SIGNATURE
Цифровая подпись
 
Примечание Если указаны спецификации ключей AT_KEYEXCHANGE и AT_SIGNATURE, идентификаторы алгоритма, используемые для создания ключа, зависят от используемого поставщика. В результате для этих ключевых спецификаций значения, возвращаемые из CryptGetKeyParam (если указан параметр KP_ALGID), зависят от используемого поставщика. Чтобы определить, какой идентификатор алгоритма используется различными поставщиками для ключевых спецификаций AT_KEYEXCHANGE и AT_SIGNATURE, см. ALG_ID.
 

[in] dwFlags

Указывает тип создаваемого ключа. Размеры сеансового ключа, ключа подписи RSA и ключей обмена ключами RSA можно задать при создании ключа. Размер ключа, представляющий длину модуля ключа в битах, задается с верхними 16 битами этого параметра. Таким образом, если необходимо создать 2048-разрядный ключ сигнатуры RSA, значение 0x08000000 объединяется с любым другим предопределенным значением dwFlags с побитовой операцией ИЛИ . Верхние 16 битов 0x08000000 0x0800 или десятичные 2048. Значение RSA1024BIT_KEY можно использовать для указания 1024-разрядного ключа RSA.

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

В частности, поставщиком служб полного шифрования RSA по умолчанию является поставщик microsoft RSA Strong Cryptographic Provider. Поставщик служб шифрования по умолчанию Diffie-Hellman подписи DSS — это поставщик служб шифрования microsoft Enhanced DSS Diffie-Hellman. Каждый из этих CSP имеет 128-разрядную длину симметричного ключа по умолчанию для RC2 и RC4 и 1024-разрядную длину ключа по умолчанию для алгоритмов открытых ключей.

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

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

Тип ключа и поставщик Минимальная длина Длина по умолчанию Максимальная длина
Базовый поставщик RSA

Signature и ExchangeKeys

384 512 16 384
Надежные и расширенные поставщики RSA

Ключи подписи и обмена

384 1024 16 384
Базовые поставщики DSS

Ключи подписи

512 1024 1024
Базовые поставщики DSS

Ключи обмена

Неприменимо Неприменимо Неприменимо
Базовые поставщики DSS/DH

Ключи подписи

512 1024 1024
Базовые поставщики DSS/DH

Ключи обмена

512 512 1024
Расширенные поставщики DSS/DH

Ключи подписи

512 1024 1024
Расширенные поставщики DSS/DH

Ключи обмена

512 1024 4096
 

Сведения о длине ключа сеанса см. в разделе CryptDeriveKey.

Дополнительные сведения о ключах, созданных с помощью поставщиков Майкрософт, см. в разделе Поставщики служб шифрования Майкрософт.

Нижние 16 бит этого параметра могут быть равны нулю или сочетанию одного или нескольких следующих значений.

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

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

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

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

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

Этот флаг применяется только к большим двоичным объектам с ключом сеанса и закрытым ключом. Он не применяется к открытым ключам, которые всегда можно экспортировать.

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

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

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

Если этот флаг указан и дескриптор поставщика в параметре hProv был создан с помощью флага CRYPT_VERIFYCONTEXT или CRYPT_SILENT , эта функция установит последнюю ошибку NTE_SILENT_CONTEXT и вернет ноль.

Windows Server 2003 и Windows XP: Этот флаг не поддерживается.

CRYPT_KEK
Этот флаг не используется.
CRYPT_INITIATOR
Этот флаг не используется.
CRYPT_NO_SALT
Этот флаг указывает, что для сорока битового симметричного ключа не выделяется значение соли. Дополнительные сведения см. в разделе Функции соляного значения.
CRYPT_ONLINE
Этот флаг не используется.
CRYPT_PREGEN
Этот флаг указывает начальное Diffie-Hellman или создание ключа DSS. Этот флаг полезен только для Diffie-Hellman и поставщиков служб конфигурации DSS. При использовании используется длина ключа по умолчанию, если длина ключа не указана в верхних 16 битах параметра dwFlags . Если параметры, включающие длину ключа, задаются для ключа PREGEN Diffie-Hellman или DSS с помощью CryptSetKeyParam, длина ключа должна быть совместима с заданной здесь длиной ключа.
CRYPT_RECIPIENT
Этот флаг не используется.
CRYPT_SF
Этот флаг не используется.
CRYPT_SGCKEY
Этот флаг не используется.
CRYPT_USER_PROTECTED
Если этот флаг установлен, пользователь получает уведомление с помощью диалогового окна или другого метода при попытке использовать этот ключ определенными действиями. Точное поведение определяется используемым поставщиком служб CSP. Если контекст поставщика был открыт с установленным флагом CRYPT_SILENT, использование этого флага приведет к сбою, а для последней ошибки задано значение NTE_SILENT_CONTEXT.
CRYPT_VOLATILE
Этот флаг не используется.

[out] phKey

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

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

Возвращает ненулевое значение в случае успешного выполнения или ноль в противном случае.

Чтобы получить дополнительные сведения об ошибке, вызовите Метод GetLastError.

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

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

Комментарии

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

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

  • Перечислите алгоритмы, поддерживаемые CSP, и получите максимальную и минимальную длину ключей для каждого алгоритма. Для этого вызовите CryptGetProvParam с PP_ENUMALGS_EX.
  • Используйте минимальную и максимальную длину, чтобы выбрать подходящую длину ключа. Не всегда рекомендуется выбирать максимальную длину, так как это может привести к проблемам с производительностью.
  • После выбора нужной длины ключа используйте верхние 16 бит параметра dwFlags , чтобы указать длину ключа.

Примеры

В следующем примере показано создание случайного ключа сеанса. Пример, включающий полный контекст для этого примера, см. в разделе Пример программы C. Шифрование файла. Другой пример использования этой функции см. в разделе Пример программы C. Расшифровка файла.

//-------------------------------------------------------------------
//  Declare the handle to the key.
HCRYPTKEY hKey; 
//-------------------------------------------------------------------
//  This example assumes that a cryptographic context 
//  has been acquired, and that it is stored in hCryptProv.
//---------------------------------------------------------------
//  Create a random session key. 

 if(CryptGenKey(
          hCryptProv, 
          ENCRYPT_ALGORITHM, 
          KEYLENGTH | CRYPT_EXPORTABLE, 
          &hKey))
 {
         printf("A session key has been created.\n");
 } 
 else
 {
          printf("Error during CryptGenKey.\n"); 
          exit(1);
 }
//-------------------------------------------------------------------
//  The key created can be exported into a key BLOB that can be
//  written to a file.
//  ...
//  When you have finished using the key, free the resource.
if (!CryptDestroyKey(hKey))
{
          printf("Error during CryptDestroyKey.\n"); 
          exit(1);
}

Требования

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

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

CryptAcquireContext

CryptDecryptKey

CryptExportKey

CryptGetKeyParam

CryptImportKey

CryptSetKeyParam

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

Проблемы потоков с поставщиками служб шифрования