Статус: Новичок
Группы: Участники
Зарегистрирован: 28.09.2018(UTC) Сообщений: 4 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Ставрополь Сказал(а) «Спасибо»: 1 раз
|
Добрый день!
Пытаюсь подписать часть XML-документа для СМЭВ с использованием примера из Crypto Pro NET SDK "SignSmevRequest.cs" запускаю в консоли: SimpleCS.exe Xml.cs.SignSmevRequest "SMEV01.Xml" "SMEV02.xml" и получаю ответ: "Найдено подписей: 1." "Подпись №1 не верна."
файл "SMEV02.xml" создается, подпись вроде бы есть, но проверку не проходит (https://dss.cryptopro.ru/Verify/Verify/) обратил внимание, что в подписаном файле строка "<DigestValue>11Ht6Fk0gwi3C76JRnrkvFu/+41RDLAdNj037aePG28=</DigestValue>" всегда одинаковая, вне зависимости от содержимого файла. То есть получается что хеш либо не рассчитывается вообще и берется непонятно откуда, либо рассчитывается не хеш блока документа, а нечто другое (может MAC-адрес).
Подскажите как в этом примере рассчитывается хеш?
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 28.09.2018(UTC) Сообщений: 4 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Ставрополь Сказал(а) «Спасибо»: 1 раз
|
Для удобства добавил еще 3 параметра которые передаются через консоль: 1) номер сертификата 2) идентификатор узла для подписи 3) не обязательный параметр, указывающий на требуемое действие "S" - подписать - "V" проверить получилось так: Код:
// Разбираем аргументы
if (args.Length < 4)
{
Console.WriteLine("<doc_to_sign> <signed_doc> <CertNumber> <IdReferens> <may be S or V>");
return;
}
// Ищем сертификат для подписи.
X509Store certStore = new X509Store(StoreLocation.CurrentUser);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certs = certStore.Certificates.Find(X509FindType.FindBySerialNumber, args[2], false);
// Проверяем, что нашли сертификат.
if (certs.Count == 0)
{
Console.WriteLine("Сертификат не найден.");
return;
}
X509Certificate2 Certificate = certs[0];
string SV = "";
if (args.Length == 5)
{
SV = args[4];
}
if (args.Length < 5)
{
//args[4] = "A";
SV = "A";
}
if (SV == "S" || SV == "s" || SV == "A")
{
// Подписываем запрос
SignXmlFile(args[0], args[1], args[3], certs[0]);
}
if (SV == "V" || SV == "v" || SV == "A")
{
// Проверяем подпись
VerifyXmlFile(args[1]);
}
}
// Подписывает файл XML с помощью заданного сертификата и сохраняет подписанный документ
// в новый файл.
static void SignXmlFile(string FileName, string SignedFileName, string IdReferens, X509Certificate2 Certificate)
{
// Создаем новый документ XML.
XmlDocument doc = new XmlDocument();
.....
Опытным путём установил, что какие бы "полезные" данные не содержались в документе хеш всегда один и тот же. Единственное что влияет на хеш, это как ни странно идентификатор узла подписи! т.е. <Reference URI="#SIGNED_BY_CALLER"> и <Reference URI="#REQUES"> дадут разные значения хеша, а остальные изменения в документе на хеш не влияют вообще. Пример документа для подписи: Код:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:eln="http://ru/ibs/fss/ln/ws/FileOperationsLn.wsdl">
<soapenv:Header>
<wsse:Security soapenv:actor="REQUEST">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="REQUEST"></wsse:BinarySecurityToken>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#REQUEST" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"></wsse:Reference>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<GetRequestRequest xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.2">
<MessageTypeSelector xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.2" wsu:Id="REQUEST">
<NamespaceURI></NamespaceURI>
<RootElementLocalName></RootElementLocalName>
<Timestamp>2018-10-18T14:02:49.1049Z</Timestamp>
</MessageTypeSelector>
</GetRequestRequest>
</soapenv:Body>
</soapenv:Envelope>
Отредактировано пользователем 18 октября 2018 г. 15:32:15(UTC)
| Причина: Не указана
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
У Вас в документе два узла с одним идентификатором wsu:Id="REQUEST" - MessageTypeSelector и wsse:BinarySecurityToken. По стандарту Xml, да и по схемам СМЭВ атрибуты типа xs:ID должны быть уникальны, как минимум в пределах документа.
Когда Вы передаете идентификатор узла REQUEST выберется скорее всего первый из узлов с одинаковым идентификатором, считая от начала документа, то есть wsse:BinarySecurityToken, а не MessageTypeSelector, как ожидается по требованиям СМЭВ. По сути получается, что вы подписываете пустую заготовку для закодированного сертификата или сертификат, а не "полезные данные". Id="SIGNED_BY_CALLER" вообще не вижу в файле-примере, скорее всего там выбирается в качестве данных для подписи пустая строка. Ни то, ни другое никак не связаны с "полезными данными", соответственно неудивительно, что хэш не меняется при изменении данных. При этом все работает в соответствии со стандартом.
Измените в wsse:Reference URI="#REQUEST" и wsse:BinarySecurityToken ... wsu:Id="REQUEST" REQUEST на другое уникальное значение, например, сгенерированный UUID или "CertId-"+отпечаток сертификата. Расположение подписи тоже кажется не совсем верное, после MessageTypeSelector на одном уровне должен идти элемент CallerInformationSystemSignature, содержащий элемент Signature.
|
![thanks](/forum2/Themes/soclean/heart_small.png) 1 пользователь поблагодарил two_oceans за этот пост.
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 28.09.2018(UTC) Сообщений: 4 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Ставрополь Сказал(а) «Спасибо»: 1 раз
|
Цитата:У Вас в документе два узла с одним идентификатором wsu:Id="REQUEST" - MessageTypeSelector и wsse:BinarySecurityToken. По стандарту Xml, да и по схемам СМЭВ атрибуты типа xs:ID должны быть уникальны, как минимум в пределах документа. Спасибо! Действительно, у wsse:BinarySecurityToken вообще не должно быть id. Я уже в глаза долблюсь, столько различных примеров и описаний прочитал, даже не заметил этого косяка. Цитата:Расположение подписи тоже кажется не совсем верное, после MessageTypeSelector на одном уровне должен идти элемент CallerInformationSystemSignature, содержащий элемент Signature. Да, я просто решаю проблемы последовательно, ведь если подпись формируется не корректно, то не имеет значение в каком блоке не корректная подпись будет размещена:)
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Автор: LonWolfius ![Перейти к цитате Перейти к цитате](/forum2/Themes/soclean/icon_latest_reply.gif) Действительно, у wsse:BinarySecurityToken вообще не должно быть id. Если в KeyInfo есть wsse:Reference (ссылка на wsse:BinarySecurityToken), то id должен быть, но он не должен совпадать с другими id в документе.
|
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 28.09.2018(UTC) Сообщений: 4 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Ставрополь Сказал(а) «Спасибо»: 1 раз
|
Цитата:Если в KeyInfo есть wsse:Reference (ссылка на wsse:BinarySecurityToken), то id должен быть, но он не должен совпадать с другими id в документе. Спасибо за информацию, буду знать. Просто мне раньше не приходилось работать с ЭЦП, а в СМЭВ нужно не просто подписать часть документа, но еще и вставить подпись в ими придуманный блок. Фактически мне нужно привести XML-документ к такому виду: Код:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.2">
<soapenv:Header></soapenv:Header>
<soapenv:Body>
<ns:GetRequestRequest>
<ns2:MessageTypeSelector xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.2" xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.2" Id="SIGNED_BY_CALLER">
<ns2:NamespaceURI>http://ffoms.ru/ExecutionMedicalInsurancePolicy/1.0.0</ns2:NamespaceURI>
<ns2:RootElementLocalName>InputData</ns2:RootElementLocalName>
<ns2:Timestamp>2018-10-17T17:09:00.082+03:00</ns2:Timestamp>
</ns2:MessageTypeSelector>
<ns:CallerInformationSystemSignature>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"></ds:SignatureMethod>
<ds:Reference URI="#SIGNED_BY_CALLER">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform>
<ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"></ds:DigestMethod>
<ds:DigestValue>8jIJOcz6YtUJqIWmwMsHECpMd8sojij5ji7T4+0TXQ8=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>6iNRHJt6dB+YRAvEREZVyiFc2ewK7SrlE8zZ/P4+KcV3L1zZfTTcfTToqzPoDNo07tbdocKixSBZ4zao80WtZw==</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIIJbTCCCRygAwIBAgIKPo6vagABAA...........</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</ns:CallerInformationSystemSignature>
</ns:GetRequestRequest>
</soapenv:Body>
</soapenv:Envelope>
P.S. разбитие на строки и табуляция для удобства восприятия.
|
|
|
|
Статус: Эксперт
Группы: Участники
Зарегистрирован: 05.03.2015(UTC) Сообщений: 1,602 ![Российская Федерация Российская Федерация](/forum2/Content/images/flags/RU.png) Откуда: Иркутская область Сказал(а) «Спасибо»: 110 раз Поблагодарили: 395 раз в 366 постах
|
Да, вид должен быть примерно такой.
С точки зрения разработки самого единого сервиса СМЭВ так намного проще - подписи хранятся в блоках отдельно от подписанных данных и можно между ними вставлять что угодно не опасаясь нарушить подпись. Сам я пишу на другом языке программирования, этот вид еще не реализовал до конца. На данный момент у меня подпись формируется в отдельном "документе", потом как текст вставляется в подписываемый документ.
На глаз вроде бы в приведенном Вами виде надо чуть локальные имена пространств имен подправить (подписывается элемент MessageTypeSelector и у него должно быть в префиксе ns1, если другие пространства имен не используются в нем и его потомках, их можно не объявлять), но даже если не исправите трансформ urn://smev-gov-ru/xmldsig/transform это сделает перед вычислением хэша. В более сложных запросах (SendResponseRequest, SendRequestRequest) подписей несколько, заранее привести документ к виду возвращаемому трансформом нереально, приходится полагаться на трансформ. Как я понимаю по прочитанному, трансформ urn://smev-gov-ru/xmldsig/transform включает в себя приведение к эксклюзивному каноническому вид, поэтому сам трансформ эксклюзивного канонического вида указывать не обязательно. И наверно надо будет добавить расширение xades-T к подписи в каких-то случаях плюс формат cades для вложений. Что-то это меня в тоску вводит как представлю. Отредактировано пользователем 19 октября 2018 г. 13:15:19(UTC)
| Причина: Не указана
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close