Статус: Новичок
Группы: Участники
Зарегистрирован: 22.06.2012(UTC) Сообщений: 4 Откуда: Самара
|
С помощью примера в СДК SignSmevRequest.Он же указан по ссылке http://pastebin.com/vsYqqfMQ делаю подпись следующего сообщения: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header><Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://gucmp.ru/gosuslugi/ApprovalServiceSoap/CheckResponse</Action><h:Header xmlns:h="http://smev.gosuslugi.ru/rev111111" xmlns="http://smev.gosuslugi.ru/rev111111" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" /><h:Security xmlns:h="http://www.w3.org/2000/09/xmldsig#" xmlns="http://www.w3.org/2000/09/xmldsig#" /></s:Header><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><CheckResponse xmlns="http://gucmp.ru/gosuslugi"> <CheckResult> <Message xmlns="http://smev.gosuslugi.ru/rev111111"> <Date>0001-01-01T00:00:00</Date> </Message> <MessageData xmlns="http://smev.gosuslugi.ru/rev111111"> <AppData > <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"/> <XmlData xmlns="http://ws.ibs/Gucmp/CheckSignResponse"><?xml version="1.0" encoding="utf-16"?><root><response errorCode="0" timestamp="2012-06-21T21:44:41.8175533+04:00" /><data><field name="ApprovalID">501adec6-03d0-4fa7-b062-71c6e9ab054c</field><field name="Status">InProgress</field><field name="DocNumber">124465-12</field><field name="DocDate">2012-06-21T21:44:41.8175533+04:00</field><field name="ApprovedPeriodFrom">2012-01-22T00:00:00.0000000</field><field name="ApprovedPeriodTo">2012-02-22T00:00:00.0000000</field><field name="ApprovedRoute">МО, Чеховский р-он, п.Столбовая: ул.Труда - Варшавское шоссе - а/д М-2 "Крым" - а/д А-108 МБК - а/д М-5 "Урал" - г.Рязань, ул.Новоселковая (ремонтная база)</field><field name="SpecialConditions">1. Движение по искусственным сооружениям осуществлять в одиночном порядке.2. Движение по мостам и п/п со скоростью 15 км/ч.</field><field name="PersonName">Иванов И.И.</field><field name="PersonJob">Директор</field><field name="Attachments"><value><file><field name="Name"><value /></field><field name="FileName"><value>sample.txt</value></field><field name="ContentType"><value /></field><field name="ContentLength"><value>0</value></field></file></value><value><file><field name="Name"><value /></field><field name="FileName"><value>sample2.txt</value></field><field name="ContentType"><value /></field><field name="ContentLength"><value>0</value></field></file></value></field></data></root></XmlData> </AppData> <AppDocument> <RequestCode>req_ece3ce5a-2178-492f-8dc0-a4d0b7543742</RequestCode> <BinaryData>UEsDBC0AAAAIAJSt1UAUtZpL//////////8KABQAc2FtcGxlLnR4dAEAEAAIAAAAAAAAAAQAAAAAAAAAK4YCAFBLAwQtAAAACACUrdVAP70X+fAA=</BinaryData> </AppDocument> </MessageData> </CheckResult> </CheckResponse> </s:Body></s:Envelope> Так вот.Проверка данного сообщения не проходит. Если использую другие файлы - подпись и проверка подписи проходят. Было замечено, что в подписываемом сообщении есть тэг : <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"/> Который содержится в теле подписываемого сообщения. И если у данного тэга убрать неймспейс, то проверка нового сообщения работает. Вопрос: как влияет присутствие пространства имён http://www.w3.org/2000/09/xmldsig# в теле подписываемого сообщения на валидацию?
|
|
|
|
Статус: Сотрудник
Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC) Сообщений: 6,393 Откуда: КРИПТО-ПРО Сказал «Спасибо»: 37 раз Поблагодарили: 717 раз в 621 постах
|
Возможно влияет на XML-валидацию - Вы какой валидатор/парсер используете? |
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 22.06.2012(UTC) Сообщений: 4 Откуда: Самара
|
Для проверки подписи использую код:
// Проверяет подписи в файле XML. static void VerifyXmlFile(string SignedFileName) { // Создаем новый XML документ в памяти. XmlDocument xmlDocument = new XmlDocument();
// Сохраняем все пробельные символы, они важны при проверке // подписи. xmlDocument.PreserveWhitespace = true;
// Загружаем подписанный документ из файла. xmlDocument.Load(SignedFileName);
// Ищем все node "Signature" и сохраняем их в объекте XmlNodeList XmlNodeList nodeList = (getHeaderNode (xmlDocument) as XmlElement).GetElementsByTagName( "Signature", SignedXml.XmlDsigNamespaceUrl);
Console.WriteLine("Найдено:{0} подпис(ей).", nodeList.Count);
// Проверяем все подписи. for (int curSignature = 0; curSignature < nodeList.Count; curSignature++) { // Создаем объект SignedXml для проверки подписи документа. SmevSignedXml signedXml = new SmevSignedXml(xmlDocument);
// Загружаем узел с подписью. signedXml.LoadXml((XmlElement)nodeList[curSignature]);
// SignXml самостоятельно не найдет сертификат подписи // т.к. он лежит вне узла Signature. // Поэтому самостоятельно извлечем сертификат по ссылке из KeyInfo // и явно зададим открытый ключ для проверки подписи. XmlNodeList referenceList = signedXml.KeyInfo.GetXml().GetElementsByTagName( "Reference", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
if (referenceList.Count == 0) { throw new XmlException("Не удалось найти ссылку на сертификат"); }
// Ищем среди аттрибутов ссылку на сертификат. string binaryTokenReference = null; foreach (XmlAttribute attribute in referenceList[0].Attributes) { if (attribute.Name.ToUpper().Equals("URI")) { // Получаем ссылку на сертификат. // формат #Value. '#' - нужно выбросить. binaryTokenReference = attribute.Value.Substring(1); break; } }
if (string.IsNullOrEmpty(binaryTokenReference)) { throw new XmlException("Не удалось найти ссылку на сертификат"); }
// Получаем узел BinarySecurityToken с закодированным в base64 сертификатом XmlElement binaryTokenElement = signedXml.GetIdElement(xmlDocument, binaryTokenReference);
if (binaryTokenElement == null) { throw new XmlException("Не удалось найти сертификат"); }
// Декодируем сертификат byte[] certBytes = Convert.FromBase64String(binaryTokenElement.InnerText); X509Certificate2 cert = new X509Certificate2(); cert.Import(certBytes);
// Проверяем подпись и выводим результат. bool result = signedXml.CheckSignature(cert.PublicKey.Key);
// Выводим результат проверки подписи в консоль. if (result) Console.WriteLine("XML подпись[{0}] верна.", curSignature + 1); else Console.WriteLine("XML подпись[{0}] не верна.", curSignature + 1); } }
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 22.06.2012(UTC) Сообщений: 4 Откуда: Самара
|
Для создания подписи использую:
// Подписывает файл XML с помощью заданного сертификата и сохраняет подписанный документ // в новый файл. static string SignXmlFile(string forSign, X509Certificate2 Certificate) { // Создаем новый документ XML. XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false;
// Читаем документ из файла. doc.LoadXml(forSign);
// Создаём объект SmevSignedXml - наследник класса SignedXml с перегруженным GetIdElement // для корректной обработки атрибута wsu:Id. SmevSignedXml signedXml = new SmevSignedXml(doc);
// Задаём ключ подписи для документа SmevSignedXml. signedXml.SigningKey = Certificate.PrivateKey;
// Создаем ссылку на подписываемый узел XML. В данном примере и в методических // рекомендациях СМЭВ подписываемый узел soapenv:Body помечен идентификатором "body". Reference reference = new Reference(); reference.Uri = "#body";
// Задаём алгоритм хэширования подписываемого узла - ГОСТ Р 34.11-94. Необходимо // использовать устаревший идентификатор данного алгоритма, т.к. именно такой // идентификатор используется в СМЭВ. #pragma warning disable 612 //warning CS0612: 'CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete' is obsolete reference.DigestMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete; #pragma warning restore 612
XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigExcC14NTransform c14 = new XmlDsigExcC14NTransform(); reference.AddTransform(c14); signedXml.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(Certificate)); signedXml.KeyInfo = keyInfo; signedXml.SignedInfo.CanonicalizationMethod = c14.Algorithm;
// Задаём алгоритм подписи - ГОСТ Р 34.10-2001. Необходимо использовать устаревший // идентификатор данного алгоритма, т.к. именно такой идентификатор используется в // СМЭВ. #pragma warning disable 612 //warning CS0612: 'CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3411UrlObsolete' is obsolete signedXml.SignedInfo.SignatureMethod = CryptoPro.Sharpei.Xml.CPSignedXml.XmlDsigGost3410UrlObsolete; #pragma warning restore 612
// Вычисляем подпись. signedXml.ComputeSignature();
// Получаем представление подписи в виде XML. XmlElement xmlDigitalSignature = signedXml.GetXml();
// Добавляем необходимые узлы подписи в исходный документ в заготовленное место. doc.GetElementsByTagName("ds:Signature")[0].PrependChild( doc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignatureValue")[0], true)); doc.GetElementsByTagName("ds:Signature")[0].PrependChild( doc.ImportNode(xmlDigitalSignature.GetElementsByTagName("SignedInfo")[0], true));
// Добавляем сертификат в исходный документ в заготовленный узел // wsse:BinarySecurityToken. doc.GetElementsByTagName("wsse:BinarySecurityToken")[0].InnerText = xmlDigitalSignature.GetElementsByTagName("X509Certificate")[0].InnerText;
// Сохраняем подписанный документ в файл. using (XmlTextWriter xmltw = new XmlTextWriter("signed.xml", new UTF8Encoding(false))) { doc.WriteTo(xmltw); }
return doc.InnerXml; }
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 22.06.2012(UTC) Сообщений: 4 Откуда: Самара
|
В качестве парсера выступает стандартный .NET XmlDocument. Вопрос в том, что он внутри вызывает - пока не знаю. Если это нужно узнать, то напишите.
|
|
|
|
Статус: Активный участник
Группы: Администраторы, Участники Зарегистрирован: 28.04.2010(UTC) Сообщений: 140 Откуда: Крипто-Про Поблагодарили: 15 раз в 14 постах
|
Добрый день, Если вы удалите пространство имен http://www.w3.org/2000/09/xmldsig# в узле Signature, то он будет "просто" узлом в теле сообщения, определенном в вашем пространстве имен xmlns="http://smev.gosuslugi.ru/rev111111" А раз указано пространство имен http://www.w3.org/2000/09/xmldsig#, значит узел обрабатывается соответственно этой схеме. Сейчас он ей не соответствует: не хватает обязательных элементов: SignedInfo, SignatureValue и т. п. В общем поведение XmlDocument корректно.
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close