Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline anonymouz  
#1 Оставлено : 13 февраля 2011 г. 0:12:30(UTC)
anonymouz

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.02.2011(UTC)
Сообщений: 5

Приветствую,

Пытаюсь сделать обертку над функциями CAPI. ( по сути это копипаста примера: "Пример на зашифрование файла" из документации к КриптоПРО 3.6, только publicKeyBlob получается из вне)

Проблема возникает на функции CryptImportKey.
Она возвращает: Набор ключей не определен.
code = 0x80090019

lpSenderContainer = "REGISTRY\\\\Ключ 1" --- тут лежит закрытый ключ
bRecipientPublicKey --- публичный ключ:
Код:
0:   06 20 00 00 23 2e 00 00 4d 41 47 31 00 02 00 00 30 12 06 07 2a 85 03 02 02 23 01 06 07 2a 85 03 
1:   02 02 1e 01 80 e1 cd 53 27 01 54 cf ad ad fa bd 2a 9e 12 41 96 7d e0 f6 72 c4 11 51 af e5 6e 9c 
2:   98 25 d9 e2 35 b8 9e 2b 2e 51 4e bd ab 55 f3 a5 3c 26 83 63 cb ef cf 42 6e 37 7f a3 88 3a 6f 49 
3:   67 f3 54 24 


остальные параметры возвращаемые, для использования из вне...

Версия КриптоПРО 3.6.6627 (на более ранней сборке, той что сертифицирована ФСБ та же проблема)



Код:
 int initEncrypt(LPWSTR lpSenderContainer, BYTE *bRecipientPublicKey, DWORD cbRecipientPublicKey, HCRYPTPROV *hProv_, HCRYPTKEY *hSenderKey_, HCRYPTKEY *hSessionKey_, HCRYPTKEY *hAgreeKey_){
	int ret = A_ERR_SUCCESS;
	
	ALG_ID ke_alg = CALG_PRO_EXPORT; // PRO_EXPORT алгоритм ключа согласования

	HCRYPTPROV hProv = 0;
	HCRYPTKEY hSenderKey = 0;
	HCRYPTKEY hSessionKey = 0;
	HCRYPTKEY hAgreeKey = 0;
	
	// создаем контекст
	if( !CryptAcquireContext(&hProv, lpSenderContainer, NULL, PROV_GOST_2001_DH, 0) ) {
        ret = A_ERR_WRONG_STORE;
		goto exit_initCrypt;
    }
    
	// Получение дескриптора закрытого ключа отправителя.
	if( !CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hSenderKey) ){
		ret = A_ERR_OPEN_STOR_REG;
		goto exit_initCrypt;
	} 
	
	// Получение ключа согласования импортом открытого ключа получателя
    // на закрытом ключе отправителя.
	if( !CryptImportKey(hProv, bRecipientPublicKey, cbRecipientPublicKey, hSenderKey, 0, &hAgreeKey) ){
		ret = A_ERR_AGREE_KEY_FAILED; // !!!!!!!!!!!!!!!!!!!!!!!! вот тут то и возникает проблема !!!!!!!!!!!!!!!!!!!!!!!
		goto exit_initCrypt;
	}

	// Установление PRO_EXPORT алгоритма ключа согласования
	if( !CryptSetKeyParam(hAgreeKey, KP_ALGID, (LPBYTE)&ke_alg, 0) ){
		ret = A_ERR_PRO_EXPORT_FAILED;
		goto exit_initCrypt;
	}

	 // Генерация сессионного ключа.
	if( !CryptGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey) ){
		ret = A_ERR_GEN_SESSION_KEY_FAILED;
		goto exit_initCrypt;
	}


exit_initCrypt:

	if(ret == A_ERR_SUCCESS){
		hProv_ = &hProv;
		hSenderKey_ = &hSenderKey;
		hSessionKey_ = &hSessionKey;
		hAgreeKey_ = &hAgreeKey;
	}else{
		// Уничтожение дескриптора закрытого ключа.
		if(hSenderKey)
			CryptDestroyKey(hSenderKey);

		// Уничтожение дескриптора сессионного ключа.
		if(hSessionKey)
			CryptDestroyKey(hSessionKey);

		// Уничтожение дескриптора ключа согласования.
		if(hAgreeKey)
			CryptDestroyKey(hAgreeKey);

		// Освобождение дескриптора провайдера.
		if(hProv) 
			CryptReleaseContext(hProv, 0);
	}

	return ret;
}


Сертификат:
Код:
-----BEGIN CERTIFICATE-----
MIIEAzCCA7CgAwIBAgIKRq87xAABAAhB1zAKBgYqhQMCAgMFADCByDFDMEEGCSqG
SIb3DQEJARY0a2hyb21vdkB0YXhjb20ucnUsIGFsZXh5YWNrQHRheGNvbS5ydSwg
cG9sQHRheGNvbS5ydTELMAkGA1UEBhMCUlUxDzANBgNVBAgTBk1vc2NvdzEPMA0G
A1UEBxMGTW9zY293MRMwEQYDVQQKEwpPT08gVGF4Y29tMSMwIQYDVQQLExpBdXRo
b3JpdHkgQ2VudHIgT09PIFRheGNvbTEYMBYGA1UEAxMPQXV0aG9yaXR5IENlbnRy
MB4XDTExMDEyMTEwMTEwMFoXDTEyMDEyMTEwMjAwMFowggEZMRgwFgYIKoUDA4ED
AQETCjM4OTk2NTQzMjUxJTAjBgkqhkiG9w0BCQEWFjk5MDAwMTBAbmFsb2cuZm9y
dXMucnUxCzAJBgNVBAYTAlJVMTEwLwYDVQQIHigAMwA4ACAEGARABDoEQwRCBEEE
OgQwBE8AIAQ+BDEEOwQwBEEEQgRMMR0wGwYDVQQHHhQEMwAuACAEGARABDoEQwRC
BEEEOjEdMBsGA1UECh4UBCIENQRBBEIEPgQyBEsEOQAgADExCjAIBgNVBAsTATAx
MTAvBgNVBAMeKAQYBDIEMAQ9BD4EMgAgBBgEMgQwBD0AIAQYBDIEMAQ9BD4EMgQ4
BEcxGTAXBgNVBAweEAQUBDgEQAQ1BDoEQgQ+BEAwYzAcBgYqhQMCAhMwEgYHKoUD
AgIkAAYHKoUDAgIeAQNDAARA6eva7qBJ9yQBki7CommPJdKBniFekZ3DpsXBualY
5nS/sBFcfZkxvrkKGfcdKzYNyhva/7xpO3t2D8L65NXoSKOCASIwggEeMA4GA1Ud
DwEB/wQEAwIE8DAdBgNVHQ4EFgQUa6nSrIpz55eu8JWSZKpXX92/CWkwLgYDVR0l
BCcwJQYIKwYBBQUHAwIGCCsGAQUFBwMEBgcqhQMCAiIGBgYqhQMDFgMwHwYDVR0j
BBgwFoAUrtohQapqewgxKfw6LZMkFnnqU/MwNAYDVR0fBC0wKzApoCegJYYjaHR0
cDovL2NybC50YXhjb20ucnUvY3JsX3RheGNvbS5jcmwwOwYIKwYBBQUHAQEELzAt
MCsGCCsGAQUFBzAChh9odHRwOi8vY3JsLnRheGNvbS5ydS9jYWNlcnQuY2VyMCkG
A1UdIAQiMCAwDgYMKoUDA4EDh3YAAwYAMA4GDCqFAwOBA4d2AAMBATAKBgYqhQMC
AgMFAANBADHJAu+3PsfQHYkkRUNC8x72Ba5vN6zEn1KtPqVCEc6ugMu+Aws1e55V
2B0BKDNtkiJMoUh4k3q8BYs0OlYp8GQ=
-----END CERTIFICATE-----

Код:
Проверка завершена успешно     	ошибок не обнаружено
Контейнер закрытого ключа      	
  имя                          	Ключ 1
  уникальное имя               	REGISTRY\\Ключ 1
  FQCN                         	\\.\REGISTRY\Ключ 1
  загрузка ключей              	успешно
Ключ обмена                    	доступен
  экспорт ключа                	разрешен
  алгоритм                     	ГОСТ Р 34.10-2001 DH
                               	ГОСТ Р 34.10-2001, параметры обмена по умолчанию
                               	ГОСТ Р 34.11-94, параметры по умолчанию
  сертификат в контейнере      	соответствует закрытому ключу
  имя сертификата              	Иванов Иван Иванович
  субъект                      	OID.1.2.643.3.131.1.1=3899654325, E=9900010@nalog.forus.ru, C=RU, S=38 Иркутская область, L=г. Иркутск, O=Тестовый 1, OU=0, CN=Иванов Иван Иванович, T=Директор
  поставщик                    	E="khromov@taxcom.ru, alexyack@taxcom.ru, pol@taxcom.ru", C=RU, S=Moscow, L=Moscow, O=OOO Taxcom, OU=Authority Centr OOO Taxcom, CN=Authority Centr
  действителен с               	21 января 2011 г. 16:11:00
  действителен по              	21 января 2012 г. 16:20:00
  серийный номер               	46AF 3BC4 0001 0008 41D7
Ключ подписи                   	отсутствует


Заранее благодарен за помощь

Отредактировано пользователем 13 февраля 2011 г. 0:57:13(UTC)  | Причина: Не указана

Offline Максим Коллегин  
#2 Оставлено : 13 февраля 2011 г. 2:24:40(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,393
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 37 раз
Поблагодарили: 717 раз в 621 постах
Откуда получен открытый ключ? Он должен быть в формате PUBLICKEY_BLOB.
Знания в базе знаний, поддержка в техподдержке
Offline anonymouz  
#3 Оставлено : 13 февраля 2011 г. 9:49:23(UTC)
anonymouz

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.02.2011(UTC)
Сообщений: 5

Цитата:
Откуда получен открытый ключ? Он должен быть в формате PUBLICKEY_BLOB.

Публичный ключ получаю из сертификата в der кодировке.
Ключ в этом формате http://msdn.microsoft.co...387459%28v=vs.85%29.aspx
Этот кусок кода работает, так как он же используется в шифрование CryptEncryptMessage (для получение дескриптора ключа по файлу сертификата)

Код:
bEncoded --- публичный ключ из сертификата в der кодировке
....
На вход получаем публичный ключ из сертификата в bEncoded
И выдаем его в формате PUBLICKEYBLOB
....
CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, bEncoded, cbEncoded, CRYPT_ENCODE_ALLOC_FLAG, NULL, bDecoded, dwDecoded)
...
CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING, bDecoded, hK)
....
CryptExportKey(hK, 0, PUBLICKEYBLOB, 0, null, dwBlobLen)
....
CryptExportKey(hK, 0, PUBLICKEYBLOB, 0, publicKeyBlob, dwBlobLen)
...

Отредактировано пользователем 13 февраля 2011 г. 9:57:36(UTC)  | Причина: Не указана

Offline Максим Коллегин  
#4 Оставлено : 13 февраля 2011 г. 20:56:43(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,393
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 37 раз
Поблагодарили: 717 раз в 621 постах
Странно, пришлите код целиком и контейнер. Попробуйте импортировать собственный открытый ключ.
Знания в базе знаний, поддержка в техподдержке
Offline anonymouz  
#5 Оставлено : 14 февраля 2011 г. 0:33:37(UTC)
anonymouz

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.02.2011(UTC)
Сообщений: 5

Что-то странное происходит.

Код не менял.
Теперь он же работает.

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

Из изменений только то, что установил еще один сертификат из тестового УЦ.
Offline anonymouz  
#6 Оставлено : 15 февраля 2011 г. 0:07:44(UTC)
anonymouz

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.02.2011(UTC)
Сообщений: 5

В общем зашифровать получилось... теперь проблема с расшифровкой.
Проблема в том, что код в низу, заместо исходного сообщения выдает на консоль:
Код:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 


Код:
container   --- имя контейнера закрытого ключа (в реестре, тот же что и в первом посте)
pbPublicKey --- публичный отправителя в формате PULBICKEYBLOB
cbPublicKey  --- длинна массива с публичным ключом
pbSessionKey --- сессионный ключ полученный при шифровании через  CryptExportKey(hSessionKey, hAgreeKey, SIMPLEBLOB, 0, NULL, dwSessionKey)
cbSessionKey --- длинна массива с сессионным ключом
pbIV           --- вектор инициализации, полученный при шифровании через CryptGetKeyParam(hSessionKey, DEFS.KP_IV, IV, dwIV, 0)
pbEncryped     --- зашифрованное сообщение, полученное вызовом: CryptEncrypt(hSessionKey, 0, TRUE, 0, pbEncryped, &cbEncypted, messageLength)
cbEncypted     ---  его длинна

Код:
int testDecrypt(LPCTSTR  container, BYTE* pbPublicKey, DWORD cbPublicKey, BYTE* pbSessionKey,  DWORD cbSessionKey, BYTE* pbIV,  BYTE* pbEncryped, DWORD cbEncypted){
	
	int ret = 0;
	HCRYPTPROV hProv = 0;
	HCRYPTKEY hPrivateKey = 0;
	HCRYPTKEY hSessionKey = 0;
	HCRYPTKEY hAgreeKey = 0;
	BYTE* msg =  NULL;
	
	// Копируем исходное сообщение
	msg = (BYTE*)malloc(cbEncypted);
	for(int i = 0; i < cbEncypted; i ++){
		msg[i] = pbEncryped[i];
	}
	
	// Получение дескриптора контейнера получателя с именем container,
    // находящегося в рамках провайдера.
	if(!CryptAcquireContext(&hProv, container, NULL, PROV_GOST_2001_DH, 0)){
		ret = -1;
		goto exit_test;
	}

	// Получение дескриптора закрытого ключа получателя.
	if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPrivateKey)){
		ret = -2;
		goto exit_test;
	}

	// Получение ключа согласования импортом открытого ключа отправителя
    // на закрытом ключе получателя.
	if( !CryptImportKey( hProv, pbPublicKey, cbPublicKey, hPrivateKey, 0, &hAgreeKey ) ){
		ret = -3;
		goto exit_test;
	}

	// Установление PRO_EXPORT алгоритма ключа согласования
	ALG_ID ke_alg = CALG_PRO_EXPORT;
	if(!CryptSetKeyParam(hAgreeKey, KP_ALGID, (LPBYTE)&ke_alg, 0)){
		ret = -4;
		goto exit_test;
	}

	// Получение сессионного ключа импортом зашифрованного сессионного ключа
    // на ключе Agree.
	if(!CryptImportKey(hProv, pbSessionKey, cbSessionKey, hAgreeKey, 0, &hSessionKey)){
		ret = -5;
		goto exit_test;
	}


	// Установка вектора инициализации - без него первые 8 байт
    // расшифруются неправильно.
	if(!CryptSetKeyParam(hSessionKey, KP_IV, pbIV, 0)){
		ret = -6;
		goto exit_test;
	}

	// дешифровка и печать сообщения
	if(!CryptDecrypt(hSessionKey, 0, TRUE, 0, msg, &cbEncypted)){
		ret = -7;
		goto exit_test;
	}else{
		ret = cbEncypted;
		for(int i = 0; i < ret; i++){
			if(i%32 == 0){
				printf("\n");
			}
			printf("%i ", msg[i] );
		}
		printf("\n");
	}

exit_test:
	return ret;

}
Offline anonymouz  
#7 Оставлено : 17 февраля 2011 г. 13:21:11(UTC)
anonymouz

Статус: Новичок

Группы: Участники
Зарегистрирован: 03.02.2011(UTC)
Сообщений: 5

up
Offline Максим Коллегин  
#8 Оставлено : 17 февраля 2011 г. 16:18:47(UTC)
Максим Коллегин

Статус: Сотрудник

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,393
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 37 раз
Поблагодарили: 717 раз в 621 постах
Странно все это. Давайте пример целиком - с шифрованием и расшифрованием.
Знания в базе знаний, поддержка в техподдержке
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest (3)
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.