Крипто-Про CSP

CPImportKey

Функция CPImportKey() используется для импорта криптографического ключа из ключевого блоба в контейнер криптопровайдера.

BOOL WINAPI CPImportKey(
  HCRYPTPROV hProv,
  WINCSP_CONST BYTE * pbData,
  DWORD dwDataLen,
  HCRYPTKEY hImpKey,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
pbData
[in] Указатель на буфер, содержащий ключевой блоб, произведенный с иcпользованием функции CPExportKey() данным или другим криптопровайдером, функционирующим на удаленном компьютере.
dwDataLen
[in] Длина ключевого блоба в байтах.
hImpKey
[in] Дескриптор ключа, на котором осуществляется снятие криптографической защиты импортируемого ключа. Значение этого параметра должно соответствовать значению hExpKey , определённому для функции CPExportKey() при создании ключевого блоба. После зашифрования ключевого блоба на сессионном ключе этот параметр содержит дескриптор на сессионный ключ. Если ключевой блоб не зашифрован (например, PUBLICKEYBLOB), этот параметр не используется и должен быть равен нулю.
dwFlags
[in] Значение флага. Этот параметр в настоящее время используется только, когда ключевая пара (закрытый/открытый ключи) импортируется в криптопровайдер (в форме PRIVATEKEYBLOB). Если импортируемый ключ будет заново экспортироваться, в этот параметр помещается флаг CRYPT_EXPORTABLE. Если этот флаг не используется, вызовы функции CryptExportKey в MS CryptoAPI 2.0 World Wide Web link с дескриптором ключа будут терпеть неудачу.
phKey
[out] Адрес, по которому функция копирует дескриптор импортированного ключа.

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

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата Описание
NTE_BAD_DATA Не прошёл контроль целостности импортируемого ключевого блоба.Ошибочная длина блоба.
NTE_BAD_FLAGS Параметр dwFlags содержит ошибочную величину.
NTE_BAD_KEY Один или оба из ключей, указанных hKey и hImpKey , не действительны. Байты в элементах заголовка ключевого блоба типа WORD, DWORD имеют обратный порядок по отношению к данной платформе.
NTE_BAD_TYPE Тип ключевого блоба не поддерживается этим криптопровайдером и, возможно, ошибочен.
NTE_PERM Попытка импорта ключа, когда право импорта криптопровайдером не предоставлено.
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 Носитель контейнера был удален из считывателя

Примечания

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

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

		
	...
	// Инициализация работы с драйвером
	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, pbSenderPublicKey, cbSenderPublicKey, hUserKey, 0, &hExchKey);
	CPImportKey(hProv, pbSessionKeyFromSender, &cbSessionKeyFromSender, hExchKey, 0, &hSessionKey);
	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.
	CPImportKey(hProv, pbBlkBlob, cbBlkBlob, hSessionKey, 0, &hBlkKey);
	...
	// Вариант получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации) 
	// с помощью CPDeriveKey.
		// bBlockNumber - указатель на байтовую последовательность, диверсифицирующая ключ.
	CPCreateHash(hProv, CALG_GR3411, 0, 0, &hHash);
	CPHashData(hProv, hHash, "DeriveBlkKey", sizeof("DeriveBlkKey"), 0);
	CPHashSessionKey(hProv, hHash, hSessionKey, 0);
	CPHashData(hProv, hHash, bBlockNumber, 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.

См. также:

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

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