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

Уведомление

Icon
Error

3 Страницы123>
Опции
К последнему сообщению К первому непрочитанному
Offline Ruslan  
#1 Оставлено : 22 октября 2008 г. 18:45:25(UTC)
Ruslan

Статус: Активный участник

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

Используя Gost3410CryptoServiceProvider создаю отсоединённую ЭЦП для выбранного файла.
При этом указываю параметры открытия секретного ключа пользователя, который находится в его личном хранилище сертификатов на сервере.

Цитата:

...

using (Gost3410CryptoServiceProvider Key = new Gost3410CryptoServiceProvider(cspPar))
{

// Создаем параметры для открытия секретного ключа.
CspParameters cspPar = new CspParameters();
cspPar. =...;
cspPar. =... ;
cspPar. =...;

ProviderInit = true;

// Cоздаём из подписываемого файла масиив байтов.
byte[] Data = Doc.OpenBinary();

// Объект, реализующий алгоритм хэширования ГОСТ 3411.
Gost3411CryptoServiceProvider GostHash = new Gost3411CryptoServiceProvider();

// Делаем ЭЦП для массива байтов подписываемого файла
Sign = Key.SignData(Data, GostHash);

//преобразуем массив байтов ЭЦП в строку символов
UTF8Encoding ByteConverter = new UTF8Encoding();
SignString= ByteConverter.GetString(Sign);

...


Теперь у меня в строке SignString находиться кракозябра символов, которые представляют ЭЦП.
Нужно проверить соответсвует ли ЭЦП файлу используя открытый ключь. Тосеть если я подписывал файл используя закрытый ключь конкретный сертификат, конкретного пользователя, то проверить ЭЦП я хочу с помощью открытого ключа, который доступен любому. Как найти такой ключ и как с его помощью проверить полученную ЭЦП!?
Я набил вот такой код. Мне нужно задать cspPar. Или есть какой-то иной способ?



Цитата:

// Создаем параметры для открытия открытого ключа.
CspParameters cspPar = new CspParameters();
cspPar. =...;
cspPar. =... ;
cspPar. =...;

public static Boolean VerifyDocSign(string StringSign, byte[] Data)
{
//преобразуем ЭЦП записанную в виде строки в массив байтов
UTF8Encoding ByteConverter = new UTF8Encoding();
Byte[] Sign = ByteConverter.GetBytes (StringSign);

// Объект, реализующий алгоритм хэширования ГОСТ 3411.
Gost3411CryptoServiceProvider GostHash = new Gost3411CryptoServiceProvider();
// Объект, реализующий алгоритм ГОСТ 3410.
Gost3410CryptoServiceProvider Gost = new Gost3410CryptoServiceProvider(cspPar);

//Проверяем правильность подписи и выводим результат.
bool b = Gost.VerifyData(Data,GostHash, Sign);
if (b)
{
return true;
}
else
{
return false;
}
}

Отредактировано пользователем 22 октября 2008 г. 18:49:20(UTC)  | Причина: Не указана

Offline Челпанов А.  
#2 Оставлено : 22 октября 2008 г. 19:28:00(UTC)
Челпанов А.

Статус: Активный участник

Группы: Участники
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 390
Мужчина
Откуда: КриптоПро

Поблагодарили: 2 раз в 2 постах
В этом случае лучше при создании Gost3410CryptoServiceProvider использовать конструктор по умолчанию. Все равно, кроме открытия провайдера для проверки подписи, Вам придется еще дополнительно импортировать в него открытый ключ, например при помощи функции ImportParameters.
Но в Вашем случае, это не лучший вариант. Так как, Вы все равно пользуетесь сертификатами, то лучше объекты провайдера Gost3410CryptoServiceProvider получать на основе имеющегося сертификата. Если у Вас есть X509Certificate2 CertSigner и Вы знаете, что это ГОСТ сертификат, то
Код:
(Gost3410CryptoServiceProvider)CertSigner.PublicKey.Key
уже будет содержать нужный Вам открытый ключ.

P.S. При подписи, то же лучше создавать объект Gost3410CryptoServiceProvider на основе сертификата
Код:
(Gost3410CryptoServiceProvider)CertSigner.PrivateKey

Отредактировано пользователем 22 октября 2008 г. 19:31:47(UTC)  | Причина: Не указана

С уважением, Александр.
Offline Ruslan  
#3 Оставлено : 23 октября 2008 г. 20:21:51(UTC)
Ruslan

Статус: Активный участник

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

Хм.. а можно один глупый вопрос не в тему! Размер detach ЭЦП меняется в зависемости от размера файла? И на сколько сильно!? У меня просто место под хранение ЭЦП ограничено :-( ! Желательно, что бы не больше 255 символов
Offline Василий  
#4 Оставлено : 23 октября 2008 г. 23:27:53(UTC)
Василий

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

Группы: Участники
Зарегистрирован: 02.04.2008(UTC)
Сообщений: 15
Откуда: Москва

Основа ЭЦП - это хэш. Соответственно, размер не меняется в зависимости от подписываемых данных. Вместе с включенным сертификатом - порядка 1.4 кБ.
Offline Ruslan  
#5 Оставлено : 24 октября 2008 г. 16:23:18(UTC)
Ruslan

Статус: Активный участник

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

Челпанов А. <- Спасибо за совет по извлечению ключей из сертификата.

Тут вот у меня ещё вопрос есть.
Сейчас я ,беру произвольный файл который надо подписать. Обращаюсь к личному хранилищу сертификатов пользователя, достаю сертификат с нужным именем, извлекаю из него PrivateKey. С помощью этого ключа подписываю файл.

Цитата:


// Создаем объект, реализующий алгоритм хэширования ГОСТ 3411
Gost3411CryptoServiceProvider GostHash = new Gost3411CryptoServiceProvider();

// Подписываем данные из потока.
byte[] SignedData = PrivateKey.SignData(MyFileStream, GostHash);




Получаю массив байтов из 64 элементов, который и является detach ЭЦП моего файла.

Когда мне нужно проверить ЭЦП, то я из того же сертификата пользователя извлекаю открытый ключь. А можно этот открытый ключь как-нить приделать к самой ЭЦП? И я слышал, что к ЭЦП можно приделать например информацию о человек, которому эта подпись принадлежит.
Offline Челпанов А.  
#6 Оставлено : 24 октября 2008 г. 17:30:27(UTC)
Челпанов А.

Статус: Активный участник

Группы: Участники
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 390
Мужчина
Откуда: КриптоПро

Поблагодарили: 2 раз в 2 постах
1. Собственно размер самой подписи неизменный - 64 байта. А то что у Вас размер подписи гуляет - это проблема переконвертирования подписи в строку (извините сходу не заметил :) )
Код:
UTF8Encoding ByteConverter = new UTF8Encoding();
SignString= ByteConverter.GetString(Sign);
Если Вам надо преобразование в строку, то лучше использовать Base64, благо в .Net есть класс ToBase64Transform.
2. Если Вы ограничены в размерах (не больше 255 символов), то ничего более компактного, чем Ваш собственный формат подписи с уложенным в него подписью в чистом виде, я Вам предложить не смогу. Сопоставление пользователя с его открытым ключем придется изобретать самостоятельно (а при юр. разборках придется еще и доказывать, что это его ключ, что он был действующий...). А, если подобных ограничений нет, тогда изобретать велосипед я Вам категорически не советую. Сертификаты, УЦ, подпись в виде CMS (xmldsig). В CMS есть различные варианты "приделывания открытого ключа к подписанному файлу". На уровне .Net есть целый namespace по работе с CMS - System.Security.Cryptography.Pkcs
С уважением, Александр.
Offline Ruslan  
#7 Оставлено : 30 октября 2008 г. 21:09:04(UTC)
Ruslan

Статус: Активный участник

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

Хм.. что-то мало в интернете информации по программированию с ЭЦП. Можно немного по подробнее пояснить? Вот я получил ЭЦП в виде массива байтов, используя при этом криптопровайдер Gost3410CryptoServiceProvider. Как её переделать в ЭЦП с прикреплённым к ней открытым ключём?
Offline Челпанов А.  
#8 Оставлено : 30 октября 2008 г. 21:13:43(UTC)
Челпанов А.

Статус: Активный участник

Группы: Участники
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 390
Мужчина
Откуда: КриптоПро

Поблагодарили: 2 раз в 2 постах
А в каком формате вы хотите это получить (подпись+открытый ключ)? В своем собственном? Тогда как угодно... Хоть справа, хоть слева, хоть с длинами хоть без... соединяйте два массива открытого ключа и подписи. Главное чтобы вы на том конце смогли отделить подписиь от открытого ключа и проверить

Отредактировано пользователем 30 октября 2008 г. 21:14:38(UTC)  | Причина: Не указана

С уважением, Александр.
Offline Ruslan  
#9 Оставлено : 30 октября 2008 г. 21:59:16(UTC)
Ruslan

Статус: Активный участник

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

Хорошо, передать и разобрать эти два массива байтов я смогу. А вот как проверить?
Сейчас я проверяю таким образом:
Цитата:

достал из хранилища сертификат X509Certificate2 cert2 = new X509Certificate2...

//создаём криптопровайдер
Gost3410CryptoServiceProvider KeyPublic = new Gost3410CryptoServiceProvider();
//достаём из сертификата открытый ключ
KeyPublic = (Gost3410CryptoServiceProvider)cert2.PublicKey.Key;
// Объект, реализующий алгоритм хэширования ГОСТ 3411.
Gost3411CryptoServiceProvider GostHash = new Gost3411CryptoServiceProvider();
// Cоздаём из проверяемого файла поток байтов.
Stream Data = Doc.OpenBinaryStream();
// Представляем строку ЭЦП в виде массива байтов
Sign = System.Convert.FromBase64String(SignString);
// Прроверяем ЭЦП для массива байтов, созданного из проверяемого файла
if (KeyPublic.VerifyData(Data, GostHash, Sign))
{
зашибись;
}
else
{
пипец;
}



А как проверить если у меня открытый ключь в виде массива байтов?
Offline Челпанов А.  
#10 Оставлено : 30 октября 2008 г. 22:08:39(UTC)
Челпанов А.

Статус: Активный участник

Группы: Участники
Зарегистрирован: 24.12.2007(UTC)
Сообщений: 390
Мужчина
Откуда: КриптоПро

Поблагодарили: 2 раз в 2 постах
Код:
// восстанавливаем открытый ключ ключ вместе с параметрами.
Gost3410Parameters p= new Gost3410Parameters();
p.PublicKey = ...
p.PublicKeyParamSet = ...
p.DigestParamSet = ...
//создаём криптопровайдер
Gost3410CryptoServiceProvider KeyPublic = new Gost3410CryptoServiceProvider();
// Импортируем в провайдер открытый ключ
KeyPublic.ImportParameters(p);

А дальше как в Вашем коде.
Параметры (OID) хеширования и открытого ключа можно либо передавать вместе с сообщением, либо прошить в коде (со всеми вытекающими последствиями).
С уважением, Александр.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
3 Страницы123>
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.