Функция 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 значениях, используемых с поставщиком шифрования Microsoft Base, см. в базовых алгоритмов поставщиков.

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

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

Ценность Значение
CALG_DH_EPHEM
Указывает эфемерный ключ Diffie-Hellman.
CALG_DH_SF
Задает ключ Diffie-Hellman "Магазин и пересылка".
 

Помимо создания ключей сеансов для симметричные алгоритмы, эта функция также может создавать пары открытых и закрытых ключей. Каждый клиент 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. По умолчанию поставщик служб шифрования DSS Diffie-Hellman поставщик служб шифрования — это поставщик расширенных служб DSS майкрософт Diffie-Hellman шифрования. Каждая из этих поставщиков служб по умолчанию имеет 128-разрядную длину симметричного ключа для RC2 и RC4 и 1024-разрядную длину ключа по умолчанию для алгоритмов открытого ключа.

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

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

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

Сигнатура и ExchangeKeys

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

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

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

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

512 1,024 1,024
Базовые поставщики DSS

Ключи Exchange

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

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

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

Ключи Exchange

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

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

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

Ключи Exchange

512 1,024 4,096
 

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

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

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

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

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

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

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

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

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

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 и поставщиков служб CSS. При использовании длина ключа по умолчанию будет использоваться, если длина ключа не указана в верхних 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

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

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

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

Для получения расширенных сведений об ошибке вызовите 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 [только классические приложения]
целевая платформа Виндоус
заголовка wincrypt.h
библиотеки Advapi32.lib
DLL Advapi32.dll

См. также

CryptAcquireContext

CryptDeskkey

CryptExportKey

CryptGetKeyParam

CryptImportKey

CryptSetKeyParam

функции создания ключей и функций Exchange

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