logo Обзор КриптоПро NGate для защищённого доступа к корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Alupanov  
#1 Оставлено : 29 июля 2019 г. 13:18:50(UTC)
Alupanov

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

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

signiterWOCS.txt.sgn (1kb) загружен 0 раз(а).Добрый день!

Создаю подпись вот так:
Цитата:

public byte[] TakeSign(CryptoAPI.CRYPT_SIGN_MESSAGE_PARA _csmp, IntPtr[] pbMessageInt, Int32[] cbMessage)
{
// Получаем длину буфера подписи
if (CryptoAPI.CryptSignMessage(
ref _csmp,
true,
1,
pbMessageInt,
cbMessage,
null,
out cbSignedMessageBlob))
{
Console.WriteLine($"Pазмер подписи: {cbSignedMessageBlob}");
}
else
{
Console.WriteLine("Ошибка CryptSignMessage.");
}

pbSignedMessageBlob = new byte[cbSignedMessageBlob];

//формируем подпись
if (CryptoAPI.CryptSignMessage(
ref _csmp,
true,
1,
pbMessageInt,
cbMessage,
pbSignedMessageBlob,
out cbSignedMessageBlob))
{
Console.WriteLine();
Console.WriteLine("Подпись: \n");
foreach (var el in pbSignedMessageBlob)
{
Console.Write("{0}", el.ToString("x"));
}
FileStream fs = new FileStream("signiter.txt.sgn", FileMode.OpenOrCreate);
fs.Write(pbSignedMessageBlob, 0, pbSignedMessageBlob.Length);
fs.Close();
return pbSignedMessageBlob;
}
else
{
return null;
}
}


структура
Цитата:

public CryptoAPI.CRYPT_SIGN_MESSAGE_PARA TakeSignStruct(IntPtr _cert)
{
CryptoAPI.CRYPT_SIGN_MESSAGE_PARA csmp = new CryptoAPI.CRYPT_SIGN_MESSAGE_PARA();
csmp.cbSize = Marshal.SizeOf(csmp);
csmp.dwMsgEncodingType = CryptoAPI.MY_TYPE;
csmp.pSigningCert = _cert;
csmp.HashAlgorithm.pszObjId = CryptoAPI.szOID_RSA_MD5;
csmp.HashAlgorithm.Parameters.cbData = 0;
csmp.cMsgCert = 0;
csmp.rgpMsgCert = IntPtr.Zero;
csmp.cAuthAttr = 0;
csmp.dwInnerContentType = 0;
csmp.cMsgCrl = 0;
csmp.cUnauthAttr = 0;
csmp.dwFlags = 0;
csmp.pvHashAuxInfo = IntPtr.Zero;
csmp.rgAuthAttr = IntPtr.Zero;
return csmp;
}


проверка signiter.txt.sgn при помощи cryptcp.x64 -verify проходит успешно, а cryptcp.x64 -vsignf выдает ошибку 0х20000065
1. Как получить с помощью CryptoAPI подпись, эквивалентную cryptcp.x64 -signf?
2. Что-то не так с созданием файла signiter.txt.sgn?
3. В чем разница между cryptcp.x64 -verify и cryptcp.x64 -vsignf?

Отредактировано пользователем 1 августа 2019 г. 17:15:02(UTC)  | Причина: Не указана

Offline two_oceans  
#2 Оставлено : 30 июля 2019 г. 5:58:09(UTC)
two_oceans

Статус: Эксперт

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

Сказал(а) «Спасибо»: 42 раз
Поблагодарили: 145 раз в 138 постах
По первому и третьему не могу посказать, в моем (достаточно старом) файле справки вообще нет команды vsignf.
Судя по справке 0х20000065 это "Невозможно открыть файл", возможно ошибка в командной строке. Без командной строки сложно точно сказать. Что не так с файлом тоже сложно сказать не видя сам файл. Возможно ошибка при сохранении файла. Пожалуйста, укажите какую командную строку используете и приложите файлы для воспроизводимости ситуации. По коду тоже не все гладко.
Код:
csmp.cMsgCert = 0;
csmp.rgpMsgCert = IntPtr.Zero;
Цитата:
cMsgCert - Number of elements in the rgpMsgCert array of CERT_CONTEXT structures. If set to zero no certificates are included in the signed message.
rgpMsgCert - Array of pointers to CERT_CONTEXT structures to be included in the signed message. If the pSigningCert is to be included, a pointer to it must be in the rgpMsgCert array.
Если я правильно понимаю, csmp.pSigningCert используется для подписания, но сам по себе не включается в подпись. Чтобы включить нужно его еще раз указать в rgpMsgCert и выставить cMsgCert в 1. Без этого Вы создаете подпись без включения каких-либо сертификатов, так что при проверке может быть ошибка из-за ненайденного сертификата. Обратите внимание, что некоторые системы проверки требуют включения всей цепочки сертификатов или цепочки без корневого сертификата.
Код:
csmp.HashAlgorithm.pszObjId = CryptoAPI.szOID_RSA_MD5;
csmp.HashAlgorithm.Parameters.cbData = 0;
Тут тоже полагаетесь на "магию", указывая алгоритм не-ГОСТ. Как это будет обработано, зависит от присутствующих на компьютере криптопровайдеров. Криптопро 3.x и первые релизы 4 заменят на гост-2001, новые релизы КриптоПро 4 скорее всего заменят на гост-2012, без криптопро так и останется. Лучше всего явно определять алгоритм по сертификату и не полагаться на "магию".

При записи файла игнорируете что вернулось в cbSignedMessageBlob. Мелочь конечно, но вдруг cbSignedMessageBlob не равно pbSignedMessageBlob.Length, тогда в файл запишется не все (это Вы исключаете проверкой результата) или запишется "мусор" из памяти (это остается возможно).
Сравните тему https://www.cryptopro.ru....aspx?g=posts&t=4989

Отредактировано пользователем 30 июля 2019 г. 6:02:13(UTC)  | Причина: Не указана

Offline Alupanov  
#3 Оставлено : 1 августа 2019 г. 15:39:57(UTC)
Alupanov

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

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

signiter.txt.sgn (2kb) загружен 0 раз(а). signiterWOCS.txt.sgn (1kb) загружен 0 раз(а).Добрый день!
спасибо за Ваше внимание и рекомендации.
1. Командная строка: cryptcp.x64 -vsignf .\signiter.txt.sgn - выдает Невозможно открыть файл
В то же время: cryptcp.x64 -verify .\signiter.txt.sgn - работает. Что такого должно быть в signiter.txt.sgn? При этом, если подписывать файл cryptcp.x64 -signf .\signiter.txt.sgn, а затем проверять, то, естественно, проверку проходит.
2. При cMsgCert = 1 и соответствующем rgpMsgCert = {массив указателей} - подпись вообще не создается. Даже если rgpMsgCert будет не IntPtr[], а IntPtr c прямым указателем pSigningCert - все равно подпись не создается. Где и что я упускаю?
3. Больше скажу - при попытке добавления других атрибутов - та же история: подпись не создается...
4. HashAlgorithm.pszObjId - согласен, взял .Value из сертификата, теперь ГОСТ

Отредактировано пользователем 1 августа 2019 г. 17:17:02(UTC)  | Причина: Не указана

Offline two_oceans  
#4 Оставлено : 2 августа 2019 г. 5:20:26(UTC)
two_oceans

Статус: Эксперт

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

Сказал(а) «Спасибо»: 42 раз
Поблагодарили: 145 раз в 138 постах
Автор: Alupanov Перейти к цитате
2. При cMsgCert = 1 и соответствующем rgpMsgCert = {массив указателей} - подпись вообще не создается. Даже если rgpMsgCert будет не IntPtr[], а IntPtr c прямым указателем pSigningCert - все равно подпись не создается. Где и что я упускаю?
3. Больше скажу - при попытке добавления других атрибутов - та же история: подпись не создается...
4. HashAlgorithm.pszObjId - согласен, взял .Value из сертификата, теперь ГОСТ
2. Подозреваю, что rgpMsgCert это "указатель на массив указателей", то есть хотя тип переменной pSigningCert уже указатель, при прямом указании rgpMsgCert надо не присваивать значение из pSigningCert, а взять еще раз указатель на саму переменную pSigningCert. В некоторых случаях среда программирования сделает это автоматически, но видимо тут не такой случай. Бывают еще ошибки маршаллинга.

Есть структуры и с более головоломными цепочками вроде указатель на указатель на указатель на указатель на буфер строки, обычно это отражается в префиксе переменной. Если префикс длинее чем "p" "pb" "cb" "psz" стоит ждать сюрпризов от поля структуры. Например, у меня так и не удалось задать список назначений сертификата "rgpszUsageIdentifier", хотя сформированный системой успешно прочитался программой как "указатель на массив указателей на буфер строки". Отличие на глаз было в том, что система сформировала все "в одном куске" памяти, а у меня было разбито на несколько кусков памяти, так как я заранее не знаю сколько идентификаторов будет. Видимо это критично для CryptoAPI.

3. Скорее всего с атрибутами такая же проблема - надо брать указатели еще раз или проверять маршаллинг.
4. Если Вы просто взяли какое-то значение алгоритма, то это конечно лучше, но скорее всего не на 100% верно, так как алгоритм подписи Вашим ключом не указывается напрямую ни в одном поле сертификата. Зато указан напрямую алгоритм, которым подписан Ваш сертификат удостоверяющим центром и алгоритм Вашего открытого ключа.

Алгоритм открытого ключа УЦ (соответствующий подписи УЦ) и алгоритм Вашего открытого ключа в общем случае могут отличаться (Минкомсвязь следит за совпадением для аккредитованных УЦ для них будет работать, но сертификаты тестовых УЦ или зарубежных алгоритмов могут привести к ошибке программы). Поэтому более корректный путь - взять алгоритм Вашего открытого ключа и по нему определить алгоритм подписи (для гост они имеют однозначное соответствие, но алгоритм открытого ключа имеет другое значение чем алгоритм подписи).

Отредактировано пользователем 2 августа 2019 г. 5:37:16(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
Андрей Писарев оставлено 02.08.2019(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.