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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline ainurwf  
#1 Оставлено : 20 февраля 2019 г. 10:48:44(UTC)
ainurwf

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

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

Сказал(а) «Спасибо»: 1 раз
Добрый день. Столкнулся со следующей проблемой и не могу её решить.
Работаю над подписанием SOAP сообщения с помощью КриптоПРО.NET.
Пример решения взял отсюда: https://www.cryptopro.ru...olzovaniem-kriptopro-net
Но в отличии от показанного примера, мне необходимо подписать весь XML файл целиком.
Пытаюсь это сделать убрав идентификатор на подписываемый элемент, то есть получается так:
reference.Uri = "";
Но из-за этого подпись ломается и проверка не проходит.
Я так понимаю подписание файла целиком проходит несколько иначе, никто не может подсказать как именно?

Отредактировано пользователем 20 февраля 2019 г. 17:32:05(UTC)  | Причина: Не указана

Offline two_oceans  
#2 Оставлено : 21 февраля 2019 г. 12:04:42(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 393 раз в 366 постах
Лучше бы проиллюстрировать примером файла, который получился с подписью - так будет яснее в чем причина.

Пока рискну предположить, что все сделано по статье буква в букву и изменен только reference.Uri. Подпись храниться внутри пописываемого документа (при подписи всего документа подпись обычно добавляется перед закрывающим тегом исходного документа)? Тогда хэш документа в reference рассчитан еще до добавления подписи (как минимум еще не известны хэш и значение подписи), и после добавления подписи хэш документа изменится.

В этом случае обязательно нужно к reference добавить трансформ
Цитата:
http://www.w3.org/2000/09/xmldsig#enveloped-signature
, который показывает что перед подсчетом хэша нужно удалить теги Signature, являющиеся непосредственными потомками подписанного элемента. Обычно добавляется до C14N трансформа, самым первым. Если не добавить - при проверке подпись не будет удалена из подписанного документа, хэш будет совсем другой и проверка будет неудачной.
Offline ainurwf  
#3 Оставлено : 25 февраля 2019 г. 9:04:55(UTC)
ainurwf

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

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

Сказал(а) «Спасибо»: 1 раз
Пример подписанного файла прилагаю.
А нет примера кода, который подписывал бы файл целиком? signedExample.xml (3kb) загружен 8 раз(а).
Offline ainurwf  
#4 Оставлено : 25 февраля 2019 г. 10:03:33(UTC)
ainurwf

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

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

Сказал(а) «Спасибо»: 1 раз
А вот так выглядит класс, подписывающий файл.
public static void SignXmlFile(string FileName, string SignedFileName, X509Certificate2 Certificate)
{
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(new XmlTextReader(FileName));
CustomSignedXml signedXml = new CustomSignedXml(doc);//наследуемый класс, для наличия префиксов на блоках SignatureValue и SignedInfo
signedXml.SigningKey = Certificate.PrivateKey;
Reference reference = new Reference();
reference.Uri = "";
reference.DigestMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete;
XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform();
reference.AddTransform(c14);
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
signedXml.SignedInfo.SignatureMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3410UrlObsolete;
signedXml.AddReference(reference);
signedXml.ComputeSignature("ds");
XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
doc.GetElementsByTagName("ds:Signature")[0].PrependChild(doc.ImportNode(xmlDigitalSignature.GetElementsByTagName("ds:SignatureValue")[0], true));
doc.GetElementsByTagName("ds:Signature")[0].PrependChild(doc.ImportNode(xmlDigitalSignature.GetElementsByTagName("ds:SignedInfo")[0], true));
doc.GetElementsByTagName("ds:X509Certificate")[0].InnerText = Convert.ToBase64String(Certificate.RawData);
using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName,
new UTF8Encoding(false)))
{
doc.WriteTo(xmltw);
}
}
Offline ainurwf  
#5 Оставлено : 26 февраля 2019 г. 16:27:08(UTC)
ainurwf

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

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

Сказал(а) «Спасибо»: 1 раз
Вопрос решён, ниже метод, который в итоге получился.
public static void SignXmlFile(string FileName, string SignedFileName, X509Certificate2 Key)
{
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = false;
doc.Load(new XmlTextReader(FileName));
SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = Key.PrivateKey;
Reference reference = new Reference();
reference.Uri = "";
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
reference.AddTransform(env);
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(Key));
signedXml.KeyInfo = keyInfo;
signedXml.ComputeSignature();
XmlElement xmlDigitalSignature = signedXml.GetXml();
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true));
using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName,
new UTF8Encoding(false)))
{
doc.WriteTo(xmltw);
}
}
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.