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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Stanislas Olegovich  
#1 Оставлено : 27 марта 2018 г. 16:52:00(UTC)
Stanislas Olegovich

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

Группы: Участники
Зарегистрирован: 27.03.2018(UTC)
Сообщений: 1
Российская Федерация
Откуда: Moscow

Добрый день!

В системе (Windows 10 x64) установлен КриптоПРО CSP 4.0. Задача следующая - программе необходимо при наступлении некоторых событий сгенерировать ключевую пару, сделать это прозрачно - без взаимодействия с пользователем, сохранить в некоторый файл настроек закрытый ключ, чтобы в будущем подписывать им некоторые данные, при отправке данных передавать так же и публичный ключ, для проверки подписи. Для подписи использовать гостовый алгоритм.

Компании необходимо использовать КриптоПРО. Вот тут сложности. Почитав документацию, столкнувшись с некоторыми ошибками на форуме, сгенерировать ключи всё же удалось, но это не "прозрачно" для пользователя.

Код:
bool genkeys(CryptoKeys& _outKeys)
{
	std::string expPrivKey, expPubKey;
	BYTE* bufPrivKey, *bufPubKey;
	DWORD cbpriv = 0, cbpub = 0, error = 0;

	HCRYPTPROV hProv = 0;
	BOOL success = CryptAcquireContext(&hProv,
		0,
		/*CP_KC1_GR3410_2001_PROV*/  CP_GR3410_2012_PROV, PROV_GOST_2012_256,
		/*CRYPT_SILENT - с ним не возвращается error код 0x8009001f |*/ CRYPT_NEWKEYSET);

	if (!success)
	{
		error = GetLastError();
		printf("\nLast error code is: 0x%x\n", error);
		return false;
	}

	HCRYPTKEY hKeys = 0, hPublicKey = 0;
	success = CryptGenKey(hProv, AT_SIGNATURE, 512 << 16 | CRYPT_EXPORTABLE, &hKeys);
	if (!success)
	{
		error = GetLastError();
		printf("\nLast error code is: 0x%x\n", error);
		CryptReleaseContext(hProv, 0);
		return false;
	}

	//
	// Export private key. - не работает
	//
	success = CryptExportKey(hKeys, NULL, PRIVATEKEYBLOB, 0, NULL, &cbpriv);
	if (!success)
	{
		// Can't calculate size of private key.
		error = GetLastError();
		printf("\nLast error code is: 0x%x\n", error);
		CryptDestroyKey(hKeys);
		CryptReleaseContext(hProv, 0);
		return false;
	}

// ..
// ...
// ....


	return (true);
}


1. Зачем в аргументе CryptGenKey используется этот сдвиг 512 << 16 ? Нашёл на форуме, без него не работало.
В заголовочном файле SDK: #define ALG_SID_SIMPLE_EXP 32 - понять не помогло.

2. О прозрачности. При генерации было отображено несколько окон:

- Просьба задать пароль для создаваемого контейнера.
- Вставьте и выберете контейнер для закрытого ключа.
- Подвигайте курсор мыши для генерации случайных чисел.
- А при использовании "ЭП ГОСТ Р 34.10-2001" было отображено информационное сообщение о будущем запрете использовании алгоритма.

Приложение работает как сервис в рамках localsystem без всякого участия пользователя, допустить каких-то окон нельзя.
Можно без окон сделать эту генерацию?

3. Экспортировать ключ с использованием CryptExportKey() не получается, даже размер не смог получить - наверняка что-то не правильно делаю.

4. Зачем требуется сохранение на какой-то носитель - диск, реестр? Мне нужно потом получить BLOB и сохранить данные самостоятельно в .xml некий, к примеру.

Буду очень благодарен за помощь!
Offline Андрей Писарев  
#2 Оставлено : 27 марта 2018 г. 17:01:47(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,719
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2054 раз в 1594 постах
Все окна - отключаются.

Режим SILENT
+ инициализировать ДСЧ
+ явно указать считыватель\имя контейнера
+ явно задать пароль.


Как отключить сообщение про ГОСТ 2001

Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей Писарев  
#3 Оставлено : 27 марта 2018 г. 17:02:47(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,719
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2054 раз в 1594 постах
Имя контейнера - смотреть описание в документации

Техническую поддержку оказываем тут
Наша база знаний
Offline Агафьин Сергей  
#4 Оставлено : 27 марта 2018 г. 17:35:43(UTC)
Grey

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

Группы: Участники
Зарегистрирован: 12.08.2013(UTC)
Сообщений: 834
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 5 раз
Поблагодарили: 215 раз в 174 постах
Добрый день.
Генерировать закрытые ключи можно только доверенным генератором случайных чисел. Их криптопровайдер поддерживает не так много: БиоДСЧ, Соболь (плата), Аккорд (плата) и dsrf (заранее нагенерированные данные на диске).

По поводу значения (512<<16) - это стандартный интерфейс Майкрософта, описанный на msdn. Длина ключа - это старший word флагов. Но в нашем провайдере её можно не указывать - ключ сгенерируется правильной длины на основе выбранного типа провайдера.

Экспортировать закрытый ключ "просто так" тоже нельзя. Только зашифровав его на каком-то другом ключе. Его можно либо вывести из секретного пароля (CryptDeriveKey), либо получить с помощью алгоритма согласования.
С уважением,
Сергей
Техническую поддержку оказываем здесь.
Наша база знаний.
thanks 1 пользователь поблагодарил Grey за этот пост.
Андрей * оставлено 27.03.2018(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.