Atom Лента - Форум КриптоПро - Тема:Формирование подписи XmlDsig для ГИИС ДМДК - 10Форум КриптоПро - Atom Лентаurn:https:--www-cryptopro-ru:AtomLenta:ForumKriptoPro:Tema:FormirovaniepodpisiXmlDsigdljaGIISDMDK-10:1Copyright 2024 Форум КриптоПро2024-03-29T09:27:42Zhttps://www.cryptopro.ru/forum2/Images/YAFLogo.pngForum Adminhttps://www.cryptopro.ruforum@cryptopro.rutwo_oceanshttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=36490&name=two_oceanstwo_oceanshttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=36490&name=two_oceansViacheslavhttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=60140&name=Viacheslavtwo_oceanshttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=36490&name=two_oceansViacheslavhttps://www.cryptopro.ru/forum2/default.aspx?g=profile&u=60140&name=ViacheslavYetAnotherForum.NETurn:https:--www-cryptopro-ru:ftPosts:st1:meid126949:1Формирование подписи XmlDsig для ГИИС ДМДК<table class="content postContainer_Alt" width="100%"><tr><td><div class="quote"><span class="quotetitle">Цитата:</span><blockquote>Пересадку брал из примера в КриптоПро SDK в моем случае работают обе версии и корректно так как структура не сложная. Хотя сам по началу подсаживал весь Signature.</div></div>Да, это значит, что выделение узла (тега, фрагмента) корректно захватывает объявления пространств имен из контекста предков (вышестоящих тегов) - в таком случае не поломается каноническая форма. Однако это все равно не очень хороший пример "как нужно делать", так как очень много незнакомых со спецификой программистов прочитают этот листинг и пытаются это же сделать в своей среде программирования на голых строковых переменных, которые конечно же не захватывают объявления пространств от вышестоящих тегов и у них все поломается.<br /><div class="quote"><span class="quotetitle">Цитата:</span><blockquote>Проблема решилась благодаря Вашим наводкам вся сложность оказалась в том, что сервис требует префиксы и строго "ds" ко всем дочерним узлам Signature хотя это отступ от стандарта, который говорит о плохом тоне при использовании префиксов. Я поначалу эту версию прорабатывал так как в примерах префиксы указаны но прочитав описания стандарта подумал ну раз это гос.сервис значит все должно быть по фэншую ровно по стандарту в этот момент я и пошел не потому пути поверив чёткое следование стандарту.</div></div>Рад за Вас, что у Вас получилось.<br /><br />К слову скажу, первая версия моей программы также была ориентирована на префиксы - читался префикс от Signature и искались SignedInfo, SignatureValue с именно этим префиксом. Отступления от стандарта и "плохого тона" я в этом не вижу. Поясню: предположение об одинаковом префиксе на мой взгляд гораздо естественнее чем делать пересадку подписи по кусочкам, "собирая зебру из черной и белой лошадей". Про подпись стандартом оговаривается алгоритм заполнения подписи на том же месте, где она создана (хотя технически однозначность префиксов не указана, да). Про возможность "пересадки" дочерних тегов под Signature стандарт ничего не говорит, наоборот подчеркивается, что после подписания документ править нельзя. Возможность пересобирать один документ в другой добавлена трансформом исключающей канонической формы - стандарт трансформа прекрасно живет без стандарта подписания и наоборот (в частности, у них взаимоисключающие требования к переводам строк - при подписании символы с кодом 13 удаляются шагом нормализации и никогда не могут прийти на вход трансформа). Неоднозначность (по моему мнению) оставлена скорее как место для расширения формата подписи, а возможность "собрать зебру" это непредумышленный побочный эффект.<br /><br />Если конкретная реализация не вставляет подпись в документ, а выдает Signature отдельно и формирует теги в неквалифицированной форме, несовместимой с задачей, то это не проблема реализации и не проблема стандарта. Проблема в выборе не того инструмента.<br /><br />С другой стороны, полностью соглашусь, что гораздо более корректно искать дочерние теги для Signature по адресу пространства имен, а не по фиксированному префиксу. После пары крашей моей программы проверки на файлах с этого форума, я все же переписал программу и теперь "зебры" тоже проходят проверку. Тем не менее, это тратит лишние ресурсы, на таком основании смешивание префиксов внутри Signature я все еще считаю попыткой найти приключение на энное место себе и впустую потратить время и ресурсы своих контрагентов.</td></tr></table>2021-08-31T13:41:04+03:002021-08-31T13:41:04+03:00two_oceans<table class="content postContainer_Alt" width="100%"><tr><td><div class="quote"><span class="quotetitle">Цитата:</span><blockquote>Пересадку брал из примера в КриптоПро SDK в моем случае работают обе версии и корректно так как структура не сложная. Хотя сам по началу подсаживал весь Signature.</div></div>Да, это значит, что выделение узла (тега, фрагмента) корректно захватывает объявления пространств имен из контекста предков (вышестоящих тегов) - в таком случае не поломается каноническая форма. Однако это все равно не очень хороший пример "как нужно делать", так как очень много незнакомых со спецификой программистов прочитают этот листинг и пытаются это же сделать в своей среде программирования на голых строковых переменных, которые конечно же не захватывают объявления пространств от вышестоящих тегов и у них все поломается.<br /><div class="quote"><span class="quotetitle">Цитата:</span><blockquote>Проблема решилась благодаря Вашим наводкам вся сложность оказалась в том, что сервис требует префиксы и строго "ds" ко всем дочерним узлам Signature хотя это отступ от стандарта, который говорит о плохом тоне при использовании префиксов. Я поначалу эту версию прорабатывал так как в примерах префиксы указаны но прочитав описания стандарта подумал ну раз это гос.сервис значит все должно быть по фэншую ровно по стандарту в этот момент я и пошел не потому пути поверив чёткое следование стандарту.</div></div>Рад за Вас, что у Вас получилось.<br /><br />К слову скажу, первая версия моей программы также была ориентирована на префиксы - читался префикс от Signature и искались SignedInfo, SignatureValue с именно этим префиксом. Отступления от стандарта и "плохого тона" я в этом не вижу. Поясню: предположение об одинаковом префиксе на мой взгляд гораздо естественнее чем делать пересадку подписи по кусочкам, "собирая зебру из черной и белой лошадей". Про подпись стандартом оговаривается алгоритм заполнения подписи на том же месте, где она создана (хотя технически однозначность префиксов не указана, да). Про возможность "пересадки" дочерних тегов под Signature стандарт ничего не говорит, наоборот подчеркивается, что после подписания документ править нельзя. Возможность пересобирать один документ в другой добавлена трансформом исключающей канонической формы - стандарт трансформа прекрасно живет без стандарта подписания и наоборот (в частности, у них взаимоисключающие требования к переводам строк - при подписании символы с кодом 13 удаляются шагом нормализации и никогда не могут прийти на вход трансформа). Неоднозначность (по моему мнению) оставлена скорее как место для расширения формата подписи, а возможность "собрать зебру" это непредумышленный побочный эффект.<br /><br />Если конкретная реализация не вставляет подпись в документ, а выдает Signature отдельно и формирует теги в неквалифицированной форме, несовместимой с задачей, то это не проблема реализации и не проблема стандарта. Проблема в выборе не того инструмента.<br /><br />С другой стороны, полностью соглашусь, что гораздо более корректно искать дочерние теги для Signature по адресу пространства имен, а не по фиксированному префиксу. После пары крашей моей программы проверки на файлах с этого форума, я все же переписал программу и теперь "зебры" тоже проходят проверку. Тем не менее, это тратит лишние ресурсы, на таком основании смешивание префиксов внутри Signature я все еще считаю попыткой найти приключение на энное место себе и впустую потратить время и ресурсы своих контрагентов.</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid126933:1Формирование подписи XmlDsig для ГИИС ДМДК<div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-csharp">public static void SignDmdkXml(string requestFileName, string requestSignedFileName,
X509Certificate2 certificate, bool saveFormat = true)
{
// Подгружаем документ
var xdoc = new XmlDocument
{
PreserveWhitespace = saveFormat
};
xdoc.Load(requestFileName);
// Создание подписчика XML-документа
var signedXml = new PrefixedSignedXml(xdoc,"ds")
{
// Установка ключа для создания подписи
SigningKey = certificate.PrivateKey,
SignedInfo =
{
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl,
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url
}
};
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
var dataReference = new Reference
{
Uri = "#body",
DigestMethod = CPSignedXml.XmlDsigGost3411_2012_256Url
};
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
dataReference.AddTransform(new XmlDsigExcC14NTransform());
dataReference.AddTransform(new XmlDsigSmevTransform());
signedXml.SafeCanonicalizationMethods.Add("urn://smev-gov-ru/xmldsig/transform");
// Установка ссылки на узел
signedXml.AddReference(dataReference);
// Установка информации о сертификате, который использовался для создания подписи
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = keyInfo;
// Вычисление подписи
signedXml.ComputeSignature();
// Получение XML-представления подписи
var signatureXml = signedXml.GetXml();
//// Добавление подписи в исходный документ
xdoc.GetElementsByTagName("ns:CallerSignature")[0].AppendChild(xdoc.ImportNode(signatureXml, true));
// Охраняем документ в выходной файл
if (!saveFormat)
{
var settings = new XmlWriterSettings
{
Indent = false,
NewLineChars = Empty
};
using var writer = XmlWriter.Create(requestSignedFileName, settings);
xdoc.Save(writer);
}
else
xdoc.Save(requestSignedFileName);
}
}</code></pre>
</div></div>2021-08-30T19:11:42+03:002021-08-30T19:11:42+03:00Viacheslav<div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-csharp">public static void SignDmdkXml(string requestFileName, string requestSignedFileName,
X509Certificate2 certificate, bool saveFormat = true)
{
// Подгружаем документ
var xdoc = new XmlDocument
{
PreserveWhitespace = saveFormat
};
xdoc.Load(requestFileName);
// Создание подписчика XML-документа
var signedXml = new PrefixedSignedXml(xdoc,"ds")
{
// Установка ключа для создания подписи
SigningKey = certificate.PrivateKey,
SignedInfo =
{
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl,
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url
}
};
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
var dataReference = new Reference
{
Uri = "#body",
DigestMethod = CPSignedXml.XmlDsigGost3411_2012_256Url
};
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
dataReference.AddTransform(new XmlDsigExcC14NTransform());
dataReference.AddTransform(new XmlDsigSmevTransform());
signedXml.SafeCanonicalizationMethods.Add("urn://smev-gov-ru/xmldsig/transform");
// Установка ссылки на узел
signedXml.AddReference(dataReference);
// Установка информации о сертификате, который использовался для создания подписи
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = keyInfo;
// Вычисление подписи
signedXml.ComputeSignature();
// Получение XML-представления подписи
var signatureXml = signedXml.GetXml();
//// Добавление подписи в исходный документ
xdoc.GetElementsByTagName("ns:CallerSignature")[0].AppendChild(xdoc.ImportNode(signatureXml, true));
// Охраняем документ в выходной файл
if (!saveFormat)
{
var settings = new XmlWriterSettings
{
Indent = false,
NewLineChars = Empty
};
using var writer = XmlWriter.Create(requestSignedFileName, settings);
xdoc.Save(writer);
}
else
xdoc.Save(requestSignedFileName);
}
}</code></pre>
</div></div>urn:https:--www-cryptopro-ru:ftPosts:st1:meid126932:1Формирование подписи XmlDsig для ГИИС ДМДК<table class="content postContainer_Alt" width="100%"><tr><td>Добрый день. Подписанный запрос не вижу, так что проверить не могу. Желательно прикреплять файлом, форум искажает содержимое. Не беда если запрос без переводов строк - любой браузер его отобразит с форматированием, так что специально добавлять отступы и переводы строк не нужно.<br /><br />1) По остальному напрашивается вопрос - трансформ СМЭВ точно ли нужен для этой информационной системы? В некоторых случаях системы крашатся при проверке на неопознанных трансформах;<br />2) Подписываете документ без удаления переводов строк, а записываете результат, удаляя переводы строк - потенциально может поломать подпись, так как каноникализация оставляет символы 0х10 без изменения (если они были). Желательно чтобы на подписание уже шел документ без лишних табуляций и переводов строк. Например, считали исходный, сразу записали во временный документ с Вашими настройками Writer, считали уже временный документ и его подписываете;<br />3) Пересадкой из одной подписи в другую также есть риск все поломать. Формируется не том месте или почему к этому прибегаете? В идеале вообще не пересаживать, а если пересаживаете, то весь тег Signature целиком. В частности, настораживает в коде, что берете содержимое (SignedInfo) без префиксов и вставляете в тег с префиксом ds:Signature. Если все так, то это исказит каноническую форму SignedInfo и SignatureValue будет неверно;<br /><br />Не уверен насчет класса SignedXml, есть ли там такой режим, но достаточно часто используют "шаблон подписи" - формируют содержимое подписи, оставив DigestValue и SignatureValue пустыми, а метод подписания заполняет только их.</td></tr></table>2021-08-30T14:55:10+03:002021-08-30T14:55:10+03:00two_oceans<table class="content postContainer_Alt" width="100%"><tr><td>Добрый день. Подписанный запрос не вижу, так что проверить не могу. Желательно прикреплять файлом, форум искажает содержимое. Не беда если запрос без переводов строк - любой браузер его отобразит с форматированием, так что специально добавлять отступы и переводы строк не нужно.<br /><br />1) По остальному напрашивается вопрос - трансформ СМЭВ точно ли нужен для этой информационной системы? В некоторых случаях системы крашатся при проверке на неопознанных трансформах;<br />2) Подписываете документ без удаления переводов строк, а записываете результат, удаляя переводы строк - потенциально может поломать подпись, так как каноникализация оставляет символы 0х10 без изменения (если они были). Желательно чтобы на подписание уже шел документ без лишних табуляций и переводов строк. Например, считали исходный, сразу записали во временный документ с Вашими настройками Writer, считали уже временный документ и его подписываете;<br />3) Пересадкой из одной подписи в другую также есть риск все поломать. Формируется не том месте или почему к этому прибегаете? В идеале вообще не пересаживать, а если пересаживаете, то весь тег Signature целиком. В частности, настораживает в коде, что берете содержимое (SignedInfo) без префиксов и вставляете в тег с префиксом ds:Signature. Если все так, то это исказит каноническую форму SignedInfo и SignatureValue будет неверно;<br /><br />Не уверен насчет класса SignedXml, есть ли там такой режим, но достаточно часто используют "шаблон подписи" - формируют содержимое подписи, оставив DigestValue и SignatureValue пустыми, а метод подписания заполняет только их.</td></tr></table>urn:https:--www-cryptopro-ru:ftPosts:st1:meid126922:1Формирование подписи XmlDsig для ГИИС ДМДК<table class="content postContainer" width="100%"><tr><td>Добрый день! <br /><br />Прошу помочь с подписью xml запроса на КриптоПро .Net для сервиса интеграции ГИИС ДМДК <a rel="nofollow" href="https://dmdk-exch.goznak.ru/ws/v1/exchange.wsdl" title="https://dmdk-exch.goznak.ru/ws/v1/exchange.wsdl">https://dmdk-exch.goznak.ru/ws/v1/exchange.wsdl</a><br /><br />Основной сайт <a rel="nofollow" href="https://dmdk.ru" title="https://dmdk.ru">https://dmdk.ru</a><br /><br />Сертификат валидный, подписанный запрос проходит валидацию на <a rel="nofollow" href="https://dss.cryptopro.ru/Verify/Verify/" title="https://dss.cryptopro.ru/Verify/Verify/">https://dss.cryptopro.ru/Verify/Verify/</a><br /><br />ТЗ от сервиса на стр 11, <a rel="nofollow" href="https://dmdk.ru/upload/iblock/ed3/0oai1g1cn0hdmeh3xk1e6v9z7wtpezdt/Opisanie-integratsionnogo-servisa-v3.0.15.1.pdf" title="https://dmdk.ru/upload/iblock/ed3/0oai1g1cn0hdmeh3xk1e6v9z7wtpezdt/Opisanie-integratsionnogo-servisa-v3.0.15.1.pdf">https://dmdk.ru/upload/i...go-servisa-v3.0.15.1.pdf</a><br />звучит так:<br /><br /><div class="quote"><span class="quotetitle">Цитата:</span><blockquote>Подпись формируется по стандарту XMLDSig (https://www.w3.org/TR/xmldsig-core1/).<br />Тип подписи – detached signature (отделенная подпись).<br />Над подписываемым XML-узлом RequestData осуществляются<br />преобразования <a rel="nofollow" href="http://www.w3.org/2001/10/xml-exc-c14n#" title="http://www.w3.org/2001/10/xml-exc-c14n#">http://www.w3.org/2001/10/xml-exc-c14n#</a> и urn://smevgov-ru/xmldsig/transform</div></div><br /><br /><br />Но подпись не проходит сервер в ответ пишет:<br /><br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-markup"><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring xml:lang="en">Error validate signature : -2</faultstring>
<detail>
<ErrorDetailType xmlns:ns2="urn://xsd.dmdk.goznak.ru/exchange/1.0">
<ns2:code>VerifySignature</ns2:code>
<ns2:msg>Error validate signature : -2</ns2:msg>
</ErrorDetailType>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope></code></pre>
</div></div><br /><br /><br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-csharp">public static void SignDmdkXml(string requestFileName, string requestSignedFileName, X509Certificate2 certificate)
{
// Подгружаем документ
var xdoc = new XmlDocument();
xdoc.Load(requestFileName);
// Создание подписчика XML-документа
var signedXml = new SignedXml(xdoc);
// Установка ключа для создания подписи
signedXml.SigningKey = certificate.PrivateKey;
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
signedXml.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url;
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
var dataReference = new Reference
{
Uri = "#body",
DigestMethod = CPSignedXml.XmlDsigGost3411_2012_256Url
};
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
//dataReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
var c14Trans = new XmlDsigExcC14NTransform();
dataReference.AddTransform(c14Trans);
var smevTrans = new XmlDsigSmevTransform();
dataReference.AddTransform(smevTrans);
signedXml.SafeCanonicalizationMethods.Add("urn://smev-gov-ru/xmldsig/transform");
// Установка ссылки на узел
signedXml.AddReference(dataReference);
// Установка информации о сертификате, который использовался для создания подписи
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = keyInfo;
// Вычисление подписи
signedXml.ComputeSignature();
// Получение XML-представления подписи
var signatureXml = signedXml.GetXml();
//// Добавление подписи в исходный документ
xdoc.GetElementsByTagName("ds:Signature")[0].AppendChild(xdoc.ImportNode(signatureXml.GetElementsByTagName("SignedInfo")[0], true));
xdoc.GetElementsByTagName("ds:Signature")[0].AppendChild(xdoc.ImportNode(signatureXml.GetElementsByTagName("SignatureValue")[0], true));
xdoc.GetElementsByTagName("ds:Signature")[0].AppendChild(xdoc.ImportNode(signatureXml.GetElementsByTagName("KeyInfo")[0], true));
var settings = new XmlWriterSettings
{
Indent = false,
NewLineChars = Empty
};
using (var writer = XmlWriter.Create(requestSignedFileName, settings))
{
xdoc.Save(writer);
}
}</code></pre>
</div></div><br /><br />Текст подписываемого запроса:<br /><br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-markup"><?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn://xsd.dmdk.goznak.ru/exchange/1.0">
<soapenv:Header/>
<soapenv:Body>
<ns:HealthRequest>
<ns:CallerSignature>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
</ns:CallerSignature>
<ns:RequestData id="body">
<ns:DataForTest>Test</ns:DataForTest>
</ns:RequestData>
</ns:HealthRequest>
</soapenv:Body>
</soapenv:Envelope></code></pre>
</div></div><br /><br />Очень нужна помощь, сам воюю неделю пока не выходит.<br />Заранее спасибо!</td></tr></table>2021-08-30T19:12:09+03:002021-08-30T19:12:09+03:00Viacheslav<table class="content postContainer" width="100%"><tr><td>Добрый день! <br /><br />Прошу помочь с подписью xml запроса на КриптоПро .Net для сервиса интеграции ГИИС ДМДК <a rel="nofollow" href="https://dmdk-exch.goznak.ru/ws/v1/exchange.wsdl" title="https://dmdk-exch.goznak.ru/ws/v1/exchange.wsdl">https://dmdk-exch.goznak.ru/ws/v1/exchange.wsdl</a><br /><br />Основной сайт <a rel="nofollow" href="https://dmdk.ru" title="https://dmdk.ru">https://dmdk.ru</a><br /><br />Сертификат валидный, подписанный запрос проходит валидацию на <a rel="nofollow" href="https://dss.cryptopro.ru/Verify/Verify/" title="https://dss.cryptopro.ru/Verify/Verify/">https://dss.cryptopro.ru/Verify/Verify/</a><br /><br />ТЗ от сервиса на стр 11, <a rel="nofollow" href="https://dmdk.ru/upload/iblock/ed3/0oai1g1cn0hdmeh3xk1e6v9z7wtpezdt/Opisanie-integratsionnogo-servisa-v3.0.15.1.pdf" title="https://dmdk.ru/upload/iblock/ed3/0oai1g1cn0hdmeh3xk1e6v9z7wtpezdt/Opisanie-integratsionnogo-servisa-v3.0.15.1.pdf">https://dmdk.ru/upload/i...go-servisa-v3.0.15.1.pdf</a><br />звучит так:<br /><br /><div class="quote"><span class="quotetitle">Цитата:</span><blockquote>Подпись формируется по стандарту XMLDSig (https://www.w3.org/TR/xmldsig-core1/).<br />Тип подписи – detached signature (отделенная подпись).<br />Над подписываемым XML-узлом RequestData осуществляются<br />преобразования <a rel="nofollow" href="http://www.w3.org/2001/10/xml-exc-c14n#" title="http://www.w3.org/2001/10/xml-exc-c14n#">http://www.w3.org/2001/10/xml-exc-c14n#</a> и urn://smevgov-ru/xmldsig/transform</div></div><br /><br /><br />Но подпись не проходит сервер в ответ пишет:<br /><br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-markup"><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring xml:lang="en">Error validate signature : -2</faultstring>
<detail>
<ErrorDetailType xmlns:ns2="urn://xsd.dmdk.goznak.ru/exchange/1.0">
<ns2:code>VerifySignature</ns2:code>
<ns2:msg>Error validate signature : -2</ns2:msg>
</ErrorDetailType>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope></code></pre>
</div></div><br /><br /><br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-csharp">public static void SignDmdkXml(string requestFileName, string requestSignedFileName, X509Certificate2 certificate)
{
// Подгружаем документ
var xdoc = new XmlDocument();
xdoc.Load(requestFileName);
// Создание подписчика XML-документа
var signedXml = new SignedXml(xdoc);
// Установка ключа для создания подписи
signedXml.SigningKey = certificate.PrivateKey;
// Установка алгоритма нормализации узла SignedInfo (в соответствии с методическими рекомендациями СМЭВ)
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
// Установка алгоритма хэширования (в соответствии с методическими рекомендациями СМЭВ)
signedXml.SignedInfo.SignatureMethod = CPSignedXml.XmlDsigGost3410_2012_256Url;
// Ссылка на узел, который нужно подписать, с указанием алгоритма хэширования
var dataReference = new Reference
{
Uri = "#body",
DigestMethod = CPSignedXml.XmlDsigGost3411_2012_256Url
};
// Метод преобразования, применяемый к данным перед их подписью (в соответствии с методическими рекомендациями СМЭВ)
//dataReference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
var c14Trans = new XmlDsigExcC14NTransform();
dataReference.AddTransform(c14Trans);
var smevTrans = new XmlDsigSmevTransform();
dataReference.AddTransform(smevTrans);
signedXml.SafeCanonicalizationMethods.Add("urn://smev-gov-ru/xmldsig/transform");
// Установка ссылки на узел
signedXml.AddReference(dataReference);
// Установка информации о сертификате, который использовался для создания подписи
var keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(certificate));
signedXml.KeyInfo = keyInfo;
// Вычисление подписи
signedXml.ComputeSignature();
// Получение XML-представления подписи
var signatureXml = signedXml.GetXml();
//// Добавление подписи в исходный документ
xdoc.GetElementsByTagName("ds:Signature")[0].AppendChild(xdoc.ImportNode(signatureXml.GetElementsByTagName("SignedInfo")[0], true));
xdoc.GetElementsByTagName("ds:Signature")[0].AppendChild(xdoc.ImportNode(signatureXml.GetElementsByTagName("SignatureValue")[0], true));
xdoc.GetElementsByTagName("ds:Signature")[0].AppendChild(xdoc.ImportNode(signatureXml.GetElementsByTagName("KeyInfo")[0], true));
var settings = new XmlWriterSettings
{
Indent = false,
NewLineChars = Empty
};
using (var writer = XmlWriter.Create(requestSignedFileName, settings))
{
xdoc.Save(writer);
}
}</code></pre>
</div></div><br /><br />Текст подписываемого запроса:<br /><br /><div class="code"><strong>Код:</strong><div class="innercode"><pre class="line-numbers"><code class="language-markup"><?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn://xsd.dmdk.goznak.ru/exchange/1.0">
<soapenv:Header/>
<soapenv:Body>
<ns:HealthRequest>
<ns:CallerSignature>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
</ns:CallerSignature>
<ns:RequestData id="body">
<ns:DataForTest>Test</ns:DataForTest>
</ns:RequestData>
</ns:HealthRequest>
</soapenv:Body>
</soapenv:Envelope></code></pre>
</div></div><br /><br />Очень нужна помощь, сам воюю неделю пока не выходит.<br />Заранее спасибо!</td></tr></table>