Крипто-Про 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 Используется для транспортировки ключа сессии. pbData указывает на структуру CRYPT_SIMPLEBLOB .
PUBLICKEYBLOB Используется для транспортировки открытых ключей. pbData указывает на структуру CRYPT_PUBLICKEYBLOB .
PRIVATEKEYBLOB Используется для транспортировки закрытых ключей). pbData указывает на структуру CRYPT_PRIVATEKEYBLOB .
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.
pbData
[in] Указатель на буфер данных, в который функция копирует ключевой блоб. Если значение этого параметра NULL, функция устанавливает по адресу pdwDataLen значение необходимой длины буфера и возвращает TRUE.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину ключевого блоба. При вызове функции указанный параметр содержит число байтов в буфере pbData . После выполнения функции параметр будет установлен числом байтов данных, скопированных в буфер pbData . Если буфер, соответствующий pbData , недостаточно большой, будет возвращен код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwDataLen . Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.

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

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

Примечания

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

		
	...
	CPGetUserKey(hProv, AT_KEYEXCHANGE, &hUserKey);
	...
	CPGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey);
	...
	CPImportKey(hProv, pbRecipentPublicKey, cbRecipentPublicKey, hUserKey, 0, &hExchKey);
	CPExportKey(hProv, hSessionKey, hExchKey, SIMPLEBLOB, 0, pbSessionKeyForRecipient, &cbSessionKeyForRecipient);
	...
	

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

		
	...
	// Инициализация работы с драйвером
	CPGetProvParam(hProv, PP_RANDOM, pbRandomBlobToDriver, cbRandomBlobToDriver);
	...
	// Передать инициализатор ДСЧ (pbRandomBlobToDriver) в драйвер и 
	// получить от него случайную последовательность (pbRandomFromDriver).
	...
	CPCreateHash(hProv, CALG_GR3411, 0, 0, &hDrvHash);
	CPHashData(hProv, hDrvHash, "DriverDaemon", sizeof("DriverDaemon"), 0);
	CPHashData(hProv, hDrvHash, pbRandomBlobToDriver, cbRandomBlobToDriver, 0);
	CPHashData(hProv, hDrvHash, pbRandomFromDriver, cbRandomFromDriver, 0);
	CPDeriveKey(hProv, hDrvHash, &hDrvKey);
	CPDestroyHash(hProv, hDrvHash);
	...
	// Пороизводство ключа сессии (файла, ассоциации) и подготовка
	// его для передачи получателю и в драйвер
	CPImportKey(hProv, pbRecipentPublicKey, cbRecipentPublicKey, hUserKey, 0, &hExchKey);
	CPExportKey(hProv, hSessionKey, hExchKey, SIMPLEBLOB, 0, pbSessionKeyForRecipient, &cbSessionKeyForRecipient);
	CPExportKey(hProv, hSessionKey, hDrvKey, SIMPLEBLOB, 0, pbSessionKeyForDriver, &cbSessionKeyForDriver);
	...
	// Передать pbSessionKeyForDriver в драйвер
	...
	

На основе этого ключа получаются ключи блоков (пакетов) с помощью функций CPGenKey(), CPDeriveKey() или алгоритма диверсификации ключа в функции CPImportKey().

		
	...
	// Инициализация работы с демоном (сервисом)
	...
	// Получить инициализатор ДСЧ (pbRandomBlobFromDaemon) в драйвер.
	...
	CPSetProvParam(hProv, PP_RANDOM, pbRandomBlobFromDaemon);
	CPGenRandom(hProv, cbRandomToDaemon, pbRandomToDaemon);
	CPCreateHash(hProv, CALG_GR3411, 0, 0, &hDmnHash);
	CPHashData(hProv, hDmnHash, "DriverDaemon", sizeof("DriverDaemon"), 0);
	CPHashData(hProv, hDmnHash, pbRandomBlobFromDaemon, cbRandomBlobFromDaemon, 0);
	CPHashData(hProv, hDmnHash, pbRandomToDaemon, cbRandomToDaemon, 0);
	CPDeriveKey(hProv, hDmnHash, &hDmnKey);
	CPDestroyHash(hProv, hDmnHash);
	...
	// Передать случайную последовательность демону (сервису).
	...
	// Получить pbSessionKeyFromDaemon из демона (сервиса)
	...
	CPImportKey(hProv, pbSessionKeyFromDaemon, &cbSessionKeyFromDaemon, hDmnKey, 0, &hSessionKey);
	...
	// Вариант получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации) 
	// с помощью CPGenKey.
	CPGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hBlkKey);
	CPExportKey(hProv, hBlkKey, hSessionKey, SIMPLEBLOB, 0, pbBlkBlob, &cbBlkBlob);
	...
	// Вариант получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации) 
	// с помощью CPDeriveKey.
	CPCreateHash(hProv, CALG_GR3411, 0, 0, &hHash);
	CPHashData(hProv, hHash, "DeriveBlkKey", sizeof("DeriveBlkKey"), 0);
	CPHashSessionKey(hProv, hHash, hSessionKey, 0);
	CPHashData(hProv, hHash, &dwBlockNumber, sizeof(dwBlockNumber), 0);
	CPDeriveKey(hProv, CALG_G28147, hHash, 0, &hBlkKey);
	CPDestroyHash(hProv, hHash);
	...
	// Вариант получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации) 
	// с помощью возможности диверсификации ключа функцией CPImportKey.
		// bBlockNumber байтовая последовательность, диверсифицирующая ключ.
	Blob.DiversBlobHeader.BlobHeader.bType = DIVERSKEYBLOB;
	Blob.DiversBlobHeader.BlobHeader.bVersion = 0x20;
	Blob.DiversBlobHeader.BlobHeader.reserverd = 0;
	Blob.DiversBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
	Blob.DiversBlobHeader = CALG_PRO_DIVERS;
	Blob.DiversBlobHeader = 0x31564944;
		Blob.DiversBlobHeader = sizeof(bBlockNumber);
	CopyMemory((LPBYTE)Blob.bDiversData,bBlockNumber,sizeof(bBlockNumber));
	CPImportKey(hProv, &Blob, sizeof(Blob), hSessionKey, 0, &hBlkKey);
	...
	

Требования:

Windows 2000/XP/2003: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Windows NT/95/98/ME: CSP 3.0 не поддерживает (см. КриптоПро CSP 2.0 World Wide Web link ).
Solaris: 9 Update 4 или выше.
FreeBSD: FreeBSD 5.2 или выше
Linux: RedHat 7.3, RedHad 9.0.
Файл описания: Прототип описан в файле wincsp.h.
Ядро Windows NT: IRQL < DISPATCH_LEVEL
Ядро ОС: Поддерживается только типы SIMPLEBLOB и DIVERSKEYBLOB.

См. также:

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

Крипто-Про CSP Версия: 3.0 Сборка 3293
Что Вы думаете по поводу данной статьи?
Закажите CD c Крипто-Про CSP