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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline S519  
#1 Оставлено : 18 мая 2009 г. 15:47:23(UTC)
S519

Статус: Участник

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

В файле есть открытый ключ получателя. Пытаюсь получить ключ согласования.
Если в качестве ключевой пары со стороны отправителя используется ключ типа AT_SIGNATURE, то ключ согласования я получаю без проблем.
А вот если использовать ключ типа AT_KEYEXCHANGE(как сейчас в коде ниже), то CryptImportKey возвращает ошибку NTE_KEYSET_NOT_DEF.
Код:
//--------------------------------------------------------------------
	// Получение ключевой пары ключевого обмена.
	if(!CryptGetUserKey(
		hProv,
		AT_KEYEXCHANGE,//AT_SIGNATURE,
		&phKey))
	{
		.....//error
	}
	//--------------------------------------------------------------------
	//Импортируем открытый ключ получателя.
	hPubKey = fopen( PubKeyFileName, "r+b" );
	dwBlobLen = filelength(fileno(hPubKey)); 

	pbKeyBlob = (BYTE*)malloc(dwBlobLen);
	dwBlobLen = fread(pbKeyBlob, 1,dwBlobLen, hPubKey);
	if(hPubKey) fclose(hPubKey);
	//--------------------------------------------------------------------
	//Получение ключа согласования
	if (CryptImportKey(
		hProv, 
		pbKeyBlob, 
		dwBlobLen, 
		phKey, 
		0, 
		&hAgreeKey))
	{
		printf("The agree key obtained; \n");//ключ согласования получен, если phKey типа AT_SIGNATURE
	}
	else
	{
		HandleError("Error during CryptImportKey public key.");//возвращает NTE_KEYSET_NOT_DEF если phKey типа AT_KEYEXCHANGE
	}


Ведь судя по документации
AT_KEYEXCHANGE - Предназначена для обмена сессионными ключами и ЭЦП.
AT_SIGNATURE - Предназначена для ЭЦП.
Получается, что все наоборот - с AT_SIGNATURE обмен сессионными ключами работает, обе стороны обмениваются ключами и шифрование/расшифрование происходит успешно, а с AT_KEYEXCHANGE возникают ошибки.
Это глюки недорелиза 3.6 или ошибки в коде?
Offline Максим Коллегин  
#2 Оставлено : 18 мая 2009 г. 15:54:45(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 715 раз в 620 постах
А в контейнере есть оба ключа?
Знания в базе знаний, поддержка в техподдержке
Offline S519  
#3 Оставлено : 18 мая 2009 г. 15:58:19(UTC)
S519

Статус: Участник

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

Цитата:
А в контейнере есть оба ключа?

Да, они сгенерированы, CryptGetUserKey не возвращает ошибку.
Offline Максим Коллегин  
#4 Оставлено : 18 мая 2009 г. 16:08:15(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 715 раз в 620 постах
Сходу не воспроизвелось. Приведите пример кода целиком. Желательно с ключами и сертификатами. Ну и убедитесь, что версия 3.6 последняя.
Знания в базе знаний, поддержка в техподдержке
Offline S519  
#5 Оставлено : 18 мая 2009 г. 16:28:44(UTC)
S519

Статус: Участник

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

Вот функция, все что надо для ее работы - сгенерированная пара в контейнере pszContainer и открытый ключ получателя в файле PubKeyFileName.

Открытый ключик приложил к сообщению.

Код:

int main(int argc, char *argv[])
{
        step3(CP_GR3410_2001_PROV_A,  PROV_GOST_2001_DH, CALG_GR3410EL, AT_KEYEXCHANGE);
	system("pause");
	return EXIT_SUCCESS; 
}
int step3(LPCSTR ProviderName, DWORD Prov_Type,ALG_ID SignAlgId, ALG_ID KeyExchAlgId)
{
	//--------------------------------------------------------------------
	// Объявление и инициализация переменных.
	HCRYPTPROV     hProv = NULL;
	HCRYPTKEY      phKey = NULL;
	HCRYPTKEY      hAgreeKey = NULL;
	HCRYPTKEY      hSessionKey = NULL;

	FILE			*hPubKey;
	FILE			*hSessKey;
	FILE			*hEFile;
        BYTE                *pbKeyBlob = NULL;
        DWORD             dwBlobLen;
	int			i=0;

	char			*PubKeyFileName = "ExportedKey_SCSP.txt";
	char			*FileToEncrypt = "FileToEncrypt.txt";
	char			*SessKeyFileName = "SessionKey.txt";
	char			*EncryptedFileName = "FileToDecrypt.txt";
	char			*IVFileName = "iv.txt";
	char			*ParamFileName = "key_param.txt";

	LPCTSTR		pszContainer = "GOST_CRYPTOPRO";
	//--------------------------------------------------------------------
	//Открытие контейнера с переданным именем.
	if (!CryptAcquireContext(
		&hProv,
		pszContainer,
		ProviderName,                         
		Prov_Type,
		0))
	{
		//Создание контейнера, если его не существует.
		if(GetLastError() == (DWORD)NTE_KEYSET_NOT_DEF || GetLastError() == NTE_BAD_KEYSET  )
		{
			HandleError("NO CONTAINER FOUND!");
		}
		else
		{
			HandleError("CryptAcquireContext with flag '0' failed.");
		}
	}
	//--------------------------------------------------------------------
	// Получение ключевой пары ключевого обмена.
	if(!CryptGetUserKey(
		hProv,
		AT_KEYEXCHANGE,//KeyExchAlgId,
		&phKey))
	{
		//если она не найдена в контейнере.
		if (GetLastError() == (DWORD)NTE_NO_KEY)
		{
			HandleError("NO KEY PAIR FOUND!");
		}
		else HandleError("CryptGetUserKey failed.");
	}
	//--------------------------------------------------------------------
	//Импортируем открытый ключ получателя.
	hPubKey = fopen( PubKeyFileName, "r+b" );
	dwBlobLen = filelength(fileno(hPubKey)); 

	pbKeyBlob = (BYTE*)malloc(dwBlobLen);
	dwBlobLen = fread(
		pbKeyBlob,
		1,
		dwBlobLen,
		hPubKey);
	if(hPubKey) fclose(hPubKey);
	//--------------------------------------------------------------------
	//Получение ключа согласования
	if (CryptImportKey(
		hProv, 
		pbKeyBlob, 
		dwBlobLen, 
		phKey, 
		0, 
		&hAgreeKey))
	{
		printf("The agree key created; \n");
	}
	else
	{
		HandleError("Error during CryptImportKey public key.");
	}
	///////////////////////////////////////////////////////////////////////

	//--------------------------------------------------------------------
	// Генерация сессионного ключа.
	if (CryptGenKey(     
		hProv,      
		CALG_G28147,      
		CRYPT_EXPORTABLE, 
		&hSessionKey))
	{   
		printf("Original session key is created. \n");
	}
	else
	{
		HandleError("ERROR -- CryptGenKey.");
	}
	//Записываем вектор инициализации в файл.
	ExportIV(hSessionKey,IVFileName);
	//Записываем параметры ключа в файл.
	ExportKeyParams(hSessionKey,ParamFileName);
	//Читаем из файла данные которые надо зашифровать
	hEFile = fopen( FileToEncrypt, "r+b" );
	dwBlobLen = filelength(fileno(hEFile)); //160;//OpenKeyFile3->Length;

	pbKeyBlob = (BYTE*)malloc(dwBlobLen + 1024);//+1024 для того чтобы потом можно было шифротекст туда засунуть. 
	dwBlobLen = fread(
				pbKeyBlob,
				1,
				dwBlobLen,
				hPubKey);
	if(hEFile) fclose(hEFile);
	//--------------------------------------------------------------------
	//Encrypt data, contains in pbKeyBlob
	DWORD BufLen = dwBlobLen + 1024;//DataLen;
	if(!CryptEncrypt(
		hSessionKey,
		0,
		TRUE,
		0,
		pbKeyBlob,
		&dwBlobLen,
		BufLen))
	{
		HandleError("CryptEncrypt failed.");
	}
	else
	{
		printf("Data encrypted;\n");
	}
	//--------------------------------------------------------------------
	//Открытие файла для записи в него шифротекста.
	hEFile = fopen(EncryptedFileName, "w+b" );
	if(!hEFile)
	{
		HandleError( "Problem opening the file." );
	}
	// Запись зашифрованного текста в файл.
	if(!fwrite(pbKeyBlob,
		1,
		dwBlobLen,
		hEFile))
	{
		HandleError("The public key can not be written to the file");
	}
	//Закрытие файла.
	if (hEFile) fclose(hEFile);
	//--------------------------------------------------------------------
	//Определяем длину блоба для сессионного ключа.
	if(CryptExportKey(
		hSessionKey, 
		hAgreeKey, 
		SIMPLEBLOB, 
		0, 
		NULL,
		&dwBlobLen)) 
	{
		printf("Size of the BLOB for the sender session key determined. \n");
	}
	else
	{
		HandleError("Error computing BLOB length.");
	}

	pbKeyBlob = (BYTE*)malloc(dwBlobLen);

	if(pbKeyBlob) 
	{
		printf("Memory has been allocated for the BLOB. \n");
	}
	else
	{
		HandleError("Out of memory. \n");
	}
	//--------------------------------------------------------------------
	// Экспорт сессионного ключа.
	if(CryptExportKey(
		hSessionKey, 
		hAgreeKey,
		SIMPLEBLOB, 
		0, 
		pbKeyBlob, 
		&dwBlobLen))
	{
		printf("Contents have been written to the BLOB. \n");
	}
	else
	{
		HandleError("Error during CryptExportKey.");
	}
	// Открытие файла для записи в него BLOBа сессионного ключа.
	hSessKey = fopen(SessKeyFileName, "w+b" );
	if(!hSessKey)
	{
		HandleError( "Problem opening the file." );
	}
	// Запись сессионного ключа в файл.
	if(!fwrite(pbKeyBlob,
		1,
		dwBlobLen,
		hSessKey))
	{
		HandleError("The public key can not be written to the file");
	}
	//Закрытие файла сессионного ключа.
	if (hSessKey) fclose(hSessKey);
	return EXIT_SUCCESS;
}

Отредактировано пользователем 18 мая 2009 г. 16:32:01(UTC)  | Причина: Не указана

Вложение(я):
ExportedKey_SCSP.txt (1kb) загружен 20 раз(а).

У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
Offline S519  
#6 Оставлено : 18 мая 2009 г. 17:20:02(UTC)
S519

Статус: Участник

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

Версия ядра СКЗИ: 3.6.4072 КС1
Версия продукта: 3.6.5329
Offline Татьяна  
#7 Оставлено : 18 мая 2009 г. 17:27:37(UTC)
Татьяна

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

Группы: Участники
Зарегистрирован: 06.02.2008(UTC)
Сообщений: 1,491
Откуда: Крипто-Про

Поблагодарили: 40 раз в 37 постах
Татьяна
ООО Крипто-Про
Offline S519  
#8 Оставлено : 18 мая 2009 г. 17:49:50(UTC)
S519

Статус: Участник

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

Переустановил криптопровайдер.
Теперь версия CSP 3.6.5371
Не помогло, симптомы те-же что описаны выше.
Offline Максим Коллегин  
#9 Оставлено : 18 мая 2009 г. 18:09:23(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 715 раз в 620 постах
Воспроизвел, будем разбираться.
Знания в базе знаний, поддержка в техподдержке
Offline Максим Коллегин  
#10 Оставлено : 18 мая 2009 г. 18:35:11(UTC)
Максим Коллегин

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

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

Сказал «Спасибо»: 37 раз
Поблагодарили: 715 раз в 620 постах
А открытый ключ в файле - из контейнера AT_SIGNATURE?
Знания в базе знаний, поддержка в техподдержке
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
2 Страницы12>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.