КриптоПро CSP  

CPGenKey

Функция CPGenKey() генерирует случайные криптографические ключи или ключевую пару (закрытый/открытый ключи).

BOOL WINAPI CPGenKey(
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
AlgId
[in] Идентификатор алгоритма шифрования или ЭП, для которого производится ключ. Могут быть произведены ключи следующих классов:
  • временные симметричные ключи (сессионные ключи);
  • временные (эфемерные) ключевые пары алгоритмов Диффи-Хеллмана;
  • долговременные ключевые пары, сохраняемые в ключевом контейнере.

    Возможные сессионные ключи:
    Значение AlgId Описание
    CALG_G28147 Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. Впоследствии этот ключ можно пометить как ключ для импорта/экспорта с помощью функции CPSetKeyParam().
    CALG_SYMMETRIC_512 512-битный симметричный ключ, который можно использовать в качестве ключа HMAC, использующего хэш-функцию ГОСТ Р 34.11-2012. Впоследствии этот ключ можно пометить как ключ для импорта/экспорта алгоритма KEXP15 с помощью функции CPCSetKeyParam().
    CALG_GOST_GENERIC_SECRET Симметричный ключ произвольной длины, который можно использовать в качестве ключа HMAC.
    CALG_GR3412_2015_M Ключ шифрования по ГОСТ Р 34.12-2015 и/или имитозащиты данных по ГОСТ Р 34.13-2015 Магма. Не может использоваться для экспорта/импорта.
    CALG_GR3412_2015_K Ключ шифрования по ГОСТ Р 34.12-2015 и/или имитозащиты данных по ГОСТ Р 34.13-2015 Кузнечик. Не может использоваться для экспорта/импорта.
    CALG_TLS1_MASTER Специальный ключ для реализации протокола TLS.
    Возможные эфемерные ключи Диффи-Хеллмана:
    AlgId Описание
    CALG_UECSYMMETRIC_EPHEM Эфемерный симметричный ключ. Предназначен для управления ключами в системе Универсальная электронная карта.
    CALG_DH_EL_EPHEM Эфемерная ключевая пара на базе ГОСТ Р 34.10-2001. Предназначена для обмена сессионными ключами.
    CALG_DH_GR3410_12_256_EPHEM Эфемерная ключевая пара на базе ГОСТ Р 34.10-2012 с длиной ключа 256 бит. Предназначена для обмена сессионными ключами.
    CALG_DH_GR3410_12_512_EPHEM Эфемерная ключевая пара на базе ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Предназначена для обмена сессионными ключами.
    Возможные долговременные ключевые пары:
    AlgId Описание
    AT_KEYEXCHANGE Производится ключевая пара, сохраняемая в ключевом контейнере. Предназначена для обмена сессионными ключами и ЭП. В качестве алгоритма ключевой пары выбирается алгоритм по умолчанию для hProv, параметр PP_DHOID функции CPGetProvParam().
    CALG_DH_EL_SF Производится ключевая пара согласно ГОСТ Р 34.10-2001. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
    CALG_DH_GR3410_12_256_SF Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа 256 бит. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
    CALG_DH_GR3410_12_512_SF Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
    AT_SIGNATURE Производится ключевая пара, сохраняемая в ключевом контейнере. Предназначена для ЭП. В качестве алгоритма ключевой пары выбирается алгоритм по умолчанию для hProv, параметр PP_SIGNATUREOID функции CPGetProvParam().
    CALG_GR3410EL Производится ключевая пара согласно ГОСТ Р 34.10-2001, в ключевой контейнер не заносится.
    CALG_GR3410_12_256 Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа подписи 256 бит, в ключевой контейнер не заносится.
    CALG_GR3410_12_512 Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа подписи 512 бит, в ключевой контейнер не заносится.
    AT_UECSYMMETRICKEY Производится симметричный пользовательский ключ. Предназначен для использования как мастерключ в системе производства ключей карт. Заносится в ключевой контейнер.
    CALG_UECSYMMETRIC Производится симметричный ключ. Если генерация ключа производится в именованном контексте, где нет ключа AT_UECSYMMETRICKEY, создаваемый ключ заносится в ключевой контейнер. Предназначен для использования как мастерключ в системе производства ключей карт. В ключевой контейнер заносится, если сответствующий AT_UECSYMMETRICKEY в ключевом контейнере отсутствует.
dwFlags
[in] Флаги определяют признаки производимого ключа. Размеры ключей подписи и ключей обмена могут быть установлены при выработке ключа. Размер ключа устанавливается в старших 16 битах параметра dwFlags, эти 16 бит представляют длину открытого ключа в битах. Длина открытого ключа равна 512 для ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012, длина ключа подписи 256 бит, и 1024 для ГОСТ Р 34.11-2012, длина ключа подписи 512 бит. Если длина ключа указана явно, она должна строго соответствовать алгоритму ключа и типу используемого провайдера. В настоящее время определены следующие флаги:
Значение dwFlags Описание
CRYPT_EXPORTABLE Если этот флаг установлен, то произведённый ключ может быть передан из криптопровайдера в ключевой блоб через функцию CPExportKey(). Если этот флаг не установлен, ключ не будет экспортируемым и будет доступен только в пределах текущей сессии приложению, которое создало этот ключ. Действие этого флага не распространяются на открытые ключи ключевых пар.

Экспорт закрытых ключей ключевых пар 2001 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Экспорт закрытых ключей ключевых пар 2012 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO12_EXPORT.
CRYPT_USER_PROTECTED Если этот флаг установлен, то при любом запросе на доступ к носителю закрытого ключа пользователя выводится окно диалога, запрашивающего право доступа к ключу.
CRYPT_PREGEN Если этот флаг установлен, то генерируется "пустая" ключевая пара обмена. Параметры этой ключевой пары должны быть установлены с использованием функции CPSetKeyParam().
CP_CRYPT_DH_ALLOWED Если этот флаг установлен, то закрытый ключ произведенной ключевой пары может быть использован для согласования сессионного ключа с помощью алгоритма Диффи-Хеллмана (VKO). Если данный флаг не указан, то для ключевых пар электронной подписи 2012 года согласование будет запрещено. Для ключевых пар обмена разрешено всегда.
CRYPT_FORCE_KEY_PROTECTION_HIGH Если этот флаг установлен, то производные ключи такие, как сессионный ключ Диффи-Хеллмана (VKO) и диверсифицированные по алгоритмам CALG_PRO_DIVERS, CALG_PRO12_DIVERS, CALG_KDF_TREE_GOSTR3411_2012_256, CALG_RIC_DIVERS унаследуют признак экспортируемости от мастер-ключа. По умолчанию сессионный ключ Диффи-Хеллмана является экспортируемым, а диверсифицированные ключи зависят от значения флага, переданного в функцию импорта.
phKey
[out] Адрес, по которому функция копирует дескриптор сформированного ключа (ключевой пары открытый/закрытый ключи).

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

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возвратаОписание
ERROR_INVALID_PARAMETERОдин из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGIDПараметр AlgId определяет алгоритм, не поддерживаемый криптопровайдером. Эта ошибка возвращается также в случае попытки генерации пользовательских ключей AT_KEYEXCHANGE и AT_SIGNATURE криптопровайдером, сертифицированным по уровню KC2 и выше, при отсутствии физического ДСЧ в составе СКЗИ.
NTE_BAD_FLAGSВеличина dwFlags имеет ошибочное значение.
NTE_NO_MEMORYКриптопровайдер во время операции исчерпал память.
NTE_FAILОшибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USERПользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHVПользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHVПользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKEDВвод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULLНедостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXTОперация не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARDНоситель контейнера был удален из считывателя.
NTE_EXISTSПопытка создания ключа в контейнере, где ключ уже существует.
SCARD_E_NO_KEY_CONTAINERКонтекст открыт с флагом CRYPT_DEFAULT_CONTAINER_OPTIONAL, и не связан ни с одним контейнером, поэтому выполнение данной операции недоступно.
SCARD_E_UNSUPPORTED_FEATUREСмарт-карта не предназначена для генерации заданных ключей.

Примечания

Если при запросе функции CPAcquireContext() был создан ключевой контейнер с признаком CRYPT_VERIFYCONTEXT, прикладные программы не могут создавать долговременные ключевые пары. В этом случае функция CPGenKey() возвращает код ошибки NTE_PERM. Когда ключи порождаются для симметричного шифрования, по умолчанию ключ будет установлен в шифратор в режиме гаммирования с обратной связью (CFB) со случайным начальным вектором. Эти параметры могут быть получены с использованием функции CPSetKeyParam() и частично изменены функцией CPSetKeyParam()

Функция CPGenKey() получает ключ с программного ДСЧ контекста криптопровайдера hProv, который инициализируется при выполнении функции CPAcquireContext() c накопленного в контейнере ключевого носителя состояния ДСЧ и установленного в системе физического ДСЧ. Криптопровайдер "КриптоПро CSP-ECC/TLS" гарантирует инициализацию состояния ДСЧ контейнера ключевого носителя с физического или, если нет физического, с БиоДСЧ.

В случае, если контекст криптопровайдера открыт в режиме CRYPT_VERIFYCONTEXT, и в системе не установлено физического ДСЧ, программный ДСЧ инициализируется с накапливаемого в реестре общесистемного состояния ДСЧ и накопленных состояний ДСЧ всех открытых ранее контейнеров ключевых носителей в рамках времени жизни разделяемой библиотеки "КриптоПро CSP 5.0". Для гарантированной инициализации программного ДСЧ с физического ДСЧ, в случае если ранее не открывались контейнеры ключевых носителей, следует использовать функцию CPSetProvParam() с флагом PP_USE_HARDWARE_RNG.

Функция CPGenKey() при выработке долговременных ключевых пар всегда использует физический ДСЧ. В случае, если контекст криптопровайдера hProv открыт в режиме CRYPT_SILENT (запрет UI, необходимый БиоДСЧ), и в системе не установлен физический ДСЧ, выдаётся ошибка.

Ключи AT_UECSYMMETRICKEY, CALG_UECSYMMETRIC, CALG_UECSYMMETRIC_EPHEM имеют ограниченный функционал, предназначены для использования в ключевых системах Универсальных Электронных Карт. Данные ключи не рекомендуется использоваться в иных системах.

Заметим, что, в соответствии с общепринятой мировой практикой, в качестве длины ключа при создании указывается именно длина открытого ключа, а не присутствующая в идентификаторах алгоритмов и oid'ах длина модуля, по которому производятся операции. В отличие от, например, алгоритма RSA (в реализациях которого открытая экспонента, как правило, фиксирована, а открытый ключ представляет собой модуль n), длина открытого ключа в стандартах подписи, основанных на операциях в группе точек эллиптической кривой (ECDSA, ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012), в два раза превосходит длину модуля.

При генерации ключа подписи/обмена выбор соответствующего алгоритма производится в зависимости от типа используемого провайдера. Провайдер типа PROV_GOST_2001_DH создает ключи в соответствии с алгоритмом ГОСТ Р 34.10-2001, используется функция хэширования в соответствии с ГОСТ Р 34.11-94. Провайдер типа PROV_GOST_2012_256 создает ключи длины 256 бит в соответствии с алгоритмом ГОСТ Р 34.10-2012, в качестве алгоритма хэширования использует алгоритм ГОСТ Р 34.11-2012 (256 бит). Провайдер типа PROV_GOST_2012_512 создает ключи длины 512 бит в соответствии с алгоритмом ГОСТ Р 34.10-2012, в качестве алгоритма хэширования использует алгоритм ГОСТ Р 34.11-2012 (512 бит).

При генерации сессионного ключа CALG_G28147 параметр KP_CIPHEROID полученного ключа по умолчанию принимает установленное для провайдера значение PP_CIPHEROID, либо, после загрузки ключей из контейнера с помощью CPGetUserKey(), oid параметров шифрования, установленный в этом контейнере.

Для создания эфемеральных ключей необходимого типа с определёнными параметрами алгоритма Диффи-Хеллмана необходимо: сгенерировать "пустую" ключевую пару командой CPGenKey(hProv, algId, CRYPT_PREGEN, &hKey); затем установить тип параметров алгоритмов Диффи-Хеллмана командой CPSetKeyParam(hProv, hKey, KP_DHOID, pbOIDdata, 0); после чего непосредственно выработать значение ключа с помощью команды CPSetKeyParam(hProv, hKey, KP_X, NULL, 0);

Полученный дескриптор ключа должен в обязательном порядке быть удалён с помощью вызова функции CPDestroyKey() до вызова функции CPReleaseContext() для рабочего дескриптора криптопровайдера.

Требования:

AIX: 6/7.
FreeBSD: 11/12, pfSense 2.x.
Linux: LSB 4.x (RHEL 5/6/7/8, SuSE 11SP4/12/15, Oracle Linux 5/6/7/8, CentOS 6/7/8, Ubuntu 14.04/16.04/18.04/19.10, Linux Mint 18/19, Fedora 28/29/30/31, Debian 8/9/10 и др.).
Solaris: 10/11.
Mac OS X: 10.9/10.10/10.11/10.12/10.13/10.14/10.15.
iOS: 8/9/10/11/12/13.
Sailfish: 2/3.
Windows: 7/8/8.1/10, Server 2008/2008R2/2012/2012R2/2016/2019.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGenKey .

См. также

CPDestroyKey() ,CPExportKey() ,CPImportKey() ,CPGetKeyParam() ,CPSetKeyParam() ,CPReleaseContext() ,CPGenKey в MS CSP World Wide Web link ,CryptGenKey в MS CryptoAPI 2.0 World Wide Web link