КриптоПро CSP  

CPExportKey

Функция CPExportKey() используется для экспорта криптографических ключей из ключевого контейнера криптопровайдера, сохраняя их в защищённом виде.

BOOL WINAPI CPExportKey(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTKEY hExpKey,
  DWORD dwBlobType,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор экспортируемого ключа.
hExpKey
[in] Дескриптор ключа, на котором осуществляется криптографическая защита экспортируемого ключа. Необходимо, чтобы этот ключ был общим с получателем корреспонденции. Зашифрованные данные ключа помещаются в ключевой блоб, предназначенный для внешнего хранения и передачи по каналам связи. Алгоритмы функции экспорта ключей гарантируют, что только пользователь предназначения сможет использовать этот ключевой блоб. Для защиты ключа используется алгоритм, указанный при создании ключа экспорта. Если ключевой блоб не будет зашифрован (например, если тип ключевого блоба - PUBLICKEYBLOB), этот параметр должен быть нулевым.
dwBlobType
[in] Тип ключевого блоба, предназначенного для экспорта ключа. В настоящее время определены три типа ключевых блобов:
Тип Использование
SIMPLEBLOB Используется для транспортировки симметричных ключей CALG_G28147, CALG_SYMMETRIC_512, CALG_GR3412_2015_M, CALG_GR3412_2015_K, CALG_UECSYMMETRIC, CALG_GOST_GENERIC_SECRET. pbData указывает на структуру CRYPT_SIMPLEBLOB .
OPAQUEKEYBLOB Используется для транспортировки ключа сессии CALG_G28147 с накопленным состоянием. pbData указывает на структуру CRYPT_OPAQUEBLOB .
PUBLICKEYBLOB Используется для транспортировки открытых ключей. pbData указывает на структуру CRYPT_PUBLICKEYBLOB .
PRIVATEKEYBLOB Используется для транспортировки закрытых ключей). pbData указывает на структуру CRYPT_PRIVATEKEYBLOB .
dwFlags
[in] Значения флагов. Должен быть нулевым во всех случаях за исключением экспорта ключевой пары в PUBLICKEYBLOB. В настоящее время определены следующие значения флагов:
Значение dwFlags Описание
CRYPT_PUBLICCOMPRESS Если флаг установлен, то отрытый ключ в PUBLICKEYBLOB представляется парой (x,b), где байт b равен 2, если координата y чётная и 3 в противном случае. Если флаг не установлен, то отрытый ключ в PUBLICKEYBLOB представляется координатами (x,y) точки эллиптической кривой.
CP_CRYPT_CALCULATE_PUBLIC_KEY Если флаг установлен, то открытый ключ будет перевычислен даже при наличии сертификата.
CP_PRIMITIVE_PUBLICKEYBLOB Если флаг установлен, то структура PUBLICKEYBLOB не будет содержать информацию о параметрах экспортируемого открытого ключа.
pbData
[in] Указатель на буфер данных, в который функция копирует ключевой блоб. Если значение этого параметра NULL, функция устанавливает по адресу pdwDataLen значение необходимой длины буфера и возвращает TRUE.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину ключевого блоба. При вызове функции указанный параметр содержит число байтов в буфере pbData. После выполнения функции параметр будет установлен числом байтов данных, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно большой, будет возвращен код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.

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

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возвратаОписание
ERROR_INVALID_PARAMETERОдин из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATAБуфер pbData недостаточно большой, чтобы копировать затребованные данные.
NTE_BAD_FLAGSВеличина dwFlags имеет ненулевое значение.
NTE_BAD_KEYОдин или оба из ключей, указанных hKey и hExpKey, не действительны.
NTE_BAD_KEY_STATEПопытка экспорта ключа, когда право экспорта криптопровайдером не предоставлено; попытка экспорта на ключе, для которого разрешение экспортировать не установлено.
NTE_BAD_TYPEdwBlobType параметр определяет неизвестный тип блоба.
NTE_NO_MEMORYКриптопровайдер во время операции исчерпал память.
NTE_FAILОшибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USERПользователь прервал операцию.
SCARD_E_NO_KEY_CONTAINERКонтекст открыт с флагом CRYPT_DEFAULT_CONTAINER_OPTIONAL, и не связан ни с одним контейнером, поэтому выполнение данной операции недоступно.

Примечания

Обычно для согласования (экспорта/импорта) сессионного ключа применяют алгоритм Диффи-Хеллмана. В этом случае ключ парной связи (ключ экспорта/импорта сессионного ключа) порождается операцией импорта (см. CPImportKey()) открытого ключа получателя (отправителя) на ключевой паре отправителя (получателя). Т.е. для экспорта сессионного ключа следует выполнить следующие шаги:

	    
      ...
      CPGetUserKey(hProv, AT_KEYEXCHANGE, &hUserKey);
      ...
      CPGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey);
      ...
      CPImportKey(hProv, pbRecipentPublicKey, cbRecipentPublicKey, hUserKey, 0, &hExchKey);
      ALG_ID ke_alg = CALG_PRO_EXPORT;
      CPSetKeyParam(hProv, hExchKey, KP_ALGID, (LPBYTE)&ke_alg, 0);
      CPExportKey(hProv, hSessionKey, hExchKey, SIMPLEBLOB, 0, pbSessionKeyForRecipient, &cbSessionKeyForRecipient);
      ...
	

Для ключей 2012 в качестве алгоритма согласования сессионного ключа используется алгоритм VKO GOST R 34.10-2012-256 (на основе функции хэширования ГОСТ Р 34.11-2012-256). Для ключей 2001 используется алгоритм VKO GOST R 34.10-2001 (на основе функции хэширования ГОСТ Р 34.11-94).

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

Для экспорта сессионных ключей любого типа могут использоваться алгоритмы CALG_SIMPLE_EXPORT, CALG_MGM_EXPORT_M, CALG_MGM_EXPORT_K, CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Ключи ГОСТ Р 34.12-2015 М и ГОСТ Р 34.12-2015 К также могут быть экспортированы с использованием алгоритмов CALG_KEXP_2015_M и CALG_KEXP_2015_K. Долговременные ключи 2001 года могут быть экспортированы при помощи алгоритмов CALG_PRO_EXPORT и CALG_PRO12_EXPORT. К ключам 2012 года применим только алгоритм экспорта CALG_PRO12_EXPORT.

Для ключей 2012 года, которые используют параметры алгоритма ГОСТ 28147, отличные от параметров по умолчанию ("1.2.643.7.1.2.5.1.1", вариант ТК26 Z), идентификатор соответствующих параметров указывается в ключевом блобе. При использовании параметров по умолчанию идентификатор в блоб не записывается.

Если симметричный ключ использует параметры шифрования "1.2.643.7.1.2.5.1.1" (вариант ТК26 Z), то при экспорте данного ключа длина ключевого блоба будет больше, чем при использовании других параметров. Для обеспечения корректности работы с памятью рекомендуется предварительно запрашивать значение необходимой длины буфера для возвращаемых данных.

Пример согласования общего ключа с использованием флага CP_PRIMITIVE_PUBLICKEYBLOB:

	    
      ...
      CryptExportKey(hEphemKey, 0, PUBLICKEYBLOB, CP_PRIMITIVE_PUBLICKEYBLOB, pbBlob, &dwBlobLen);
      CryptImportKey(hProv, pbBlob, dwBlobLen, hSecretKey, CP_PRIMITIVE_PUBLICKEYBLOB, &hCommonKey);
      ...
	

Требования:

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.
Ядро ОС: Вместо неё используется аналогичная функция CPCExportKey .

См. также

CPImportKey() ,CPExportKey в MS CSP World Wide Web link ,CryptExportKey в MS CryptoAPI 2.0 World Wide Web link