В материале рассматриваются методы проверки работоспособности СМЭВ-сервисов (видов сведений) органов власти-Поставщиков данных. Также описывается способ, благодаря использованию которого можно подтвердить факт сбора Поставщиком Вашего запроса из входящей СМЭВ-очереди.
Важность мониторинга СМЭВ-сервисов
Мониторинг работоспособности ВС Поставщика — одна из первых и наиболее важных задач, с которой сталкиваются участники межведомственного взаимодействия. Отказ сервисов — достаточно частое явление. Оно может быть вызвано несколькими причинами:
- вид сведений в принципе не работоспособен;
- возникли временные сбои в связи с отказом инфраструктуры или проведением технических работ;
- вид сведений направляет ответы, которые не проходят проверку на стороне СМЭВ.
Второй и третий случаи имеют наиболее пагубные последствия для Потребителя данных. Пользователи систем межведомственного взаимодействия достаточно быстро привыкают к тому, что ответ на СМЭВ-запрос приходит в конкретные сроки. Если после продолжительной бесперебойной работы вид сведений неожиданно отказывает на стороне Поставщика, и ответы на запросы не приходят в ожидаемый («обычный») срок, пользователи ИС Потребителя начинают беспокоиться и вместо ожидания регламентных 5 дней заваливают свою службу поддержки сообщениями об инцидентах.
Для того чтобы избежать этой ситуации службе поддержки ИС Потребителя данных, а также понечным пользователям данной системы необходимо обладать полной и достоверной информацией о том, на какой «стадии обработки» находится их запрос.
Для СМЭВ 2 на Технологическом портале существовал специальный инструмент отслеживания доступности сервисов. ИТ-специалист или рядовой пользователь могли в режиме близком к реальному времени просматривать эту информацию. И если сервис становился недоступен — для пользователя это значило, что «на той стороне что-то сломалось, нужно подождать, Поставщик скоро все починит, и ответ придет». С переходом на СМЭВ 3 бессмысленным стало само понятие доступности вида сведений. При условии, что очередь запросов Потребителя не заполнена, запросы уходят в СМЭВ всегда. Но как понять дальнейшую судьбу запроса? И как в случае необходимости доказать Поставщику, что он получил запрос, но не ответил на него?
В материале будут рассмотрены следующие способы проверки работоспособности внешних (чужих) видов сведений:
- проверка факта вывода ВС в продуктивную среду;
- проверка факта запуска сервиса;
- проверка факта сбора Поставщиком запроса из очереди СМЭВ-запросов.
Проверка вывода вида сведений в продуктивную среду
Проверка выполняется достаточно легко по одному из двух сценариев.
Второй способ является более предпочтительным, так как в записи о виде сведений содержится много дополнительной полезной информации. Например, если сервис выведен только в тестовую среду — можно сравнить дату вывода с текущей. Как правило, срок между выводом ВС в тест и продуктив составляет до трех месяцев. Если разница составляет более 9 месяцев — скорее всего, ВС так и не заработает.
Проверка реальной работоспособности вида сведений
Может сложиться ощущение, что признаком работоспособности ВС является наличие у него потребителей в продуктивной среде. Однако это не так. Достаточно часто встречается ситуация, при которой ведомство получает доступ к сервису в проде, делает несколько пробных запросов, остающихся без ответа, и прекращает межведомственное взаимодействие, при этом формально оставаясь в числе потребителей.
Таких «невостребованных» сервисов достаточно много, они встречаются у ФТС, МВД, МИДа, Минкультуры, Минкомсвязи и у других ведомств. Например:
- Сведения о дорожно-транспортных происшествиях (ДТП)
- Оформление и выдача паспортов гражданина Российской Федерации, удостоверяющих личность гражданина Российской Федерации за пределами территории Российской Федерации
- Информация о нарушениях ПДД
- СНИЛС по данным лицевого счета
- Запрос изменений значений показателей из ГАС «Управление»
- Нормативы запасов топлива
- Сведения о разрешении на строительство
- и др.
Проверка доставки запроса до Поставщика
В СМЭВ предусмотрена возможность получения уведомлений о факте сбора Поставщиком запросов из очереди. Данная опция прописана в п. 10.12.3 «Правил и процедур работы в ЕСМЭВ по Методическим рекомендациям версии 3» и сформулирована как «Подключение уведомлений о доставке сообщений до получателя в соответствии с МР версии 3.х п 6.1».
Для активации опции необходимо написать соответствующий запрос в Ситуационный центр электронного правительства, указав наименование Потребителя и мнемонику ведомственной ИС.
После подключения опции по факту сбора Поставщиком запроса из очереди в систему из СМЭВ будут приходить сообщения формата:
<status>OTHER</status>
<details>Сообщение помещено в очередь к получателю, 18:22 28-06-2018</details>
Эти сообщения можно обрабатывать и показывать пользователю в виде отдельного статуса обработки СМЭВ-запроса.
Статусы запросов СМЭВ
В начале статьи поднята проблема необходимости информирования конечных пользователей информационных систем Потребителя о работоспособности видов сведений и статусах обработки запросов. Подробно используемая авторами система мониторинга и оповещения о работе СМЭВ будет рассмотрена в отдельной статье. В данном материале перечислим только наиболее важные, с точки зрения авторов, статусы обработки СМЭВ-запроса, которые должны показываться пользователю (отправителю запроса):
- «Черновик» — запрос сформирован целиком или частично, но еще не передан Пользователем на отправку;
- «В очереди на отправку» — запрос передан пользователем на отправку и проходит обработку в системе (создание СМЭВ-конверта, подписание ЭП, отправка в СМЭВ). Также этот статус получают запросы, которые СМЭВ пока отказывается принимать (например, из-за переполнения очереди в связи с большим количеством направляемых запросов), и они висят «в отправке»;
- «Ошибка отправки» — запрос не был отправлен из-за системного сбоя или не прошел проверку на стороне СМЭВ;
- «Передано в СМЭВ» — запрос передан в СМЭВ, получен индикатор запроса в СМЭВ (SMEV ID);
- «Получено Поставщиком» — Поставщик данных забрал запрос из очереди;
- «Получен ответ» — получен ответ на запрос от Поставщика данных;
- «Истекло время ожидания ответа» — отсутствует ответ от Поставщика данных в течение 5 дней.
Таким образом, если пользователь видит сообщение в статусе «Получено поставщиком», на которое слишком долго по его мнению (ощущениям) не приходит ответ, он может самостоятельно связаться с ответственным на стороне Поставщика, передать ему SMEV ID запроса и укорить долгой обработкой запроса. В свою очередь, Поставщик уже не может сказать, что не получал запрос, что сообщение «затерялось где-то в СМЭВе».
Также в нашей практике несколько раз встречалась ситуация, когда проверку на стороне СМЭВ не проходил ответ Поставщика. В этих случаях наличие информации, подтверждающей факт сбора запроса Поставщиком из входящей очереди СМЭВ, позволяло оперативно локализовать и решить проблему «слишком долгого ожидания ответа».
Система межведомственного электронного взаимодействия (СМЭВ) задумывалась как цифровая среда предоставления услуг и исполнения государственных и муниципальных функций в электронной форме.
В настоящее время СМЭВ продолжает расширять свои возможности и вовлекать все большее количество участников взаимодействия.
Что оказалось как нельзя кстати, в том числе для коммерческих организаций, в частности банков, которые все больше стремятся перевести свои услуги в цифру и сериализовать процессы.
В этой статье мы поговорим о том, как своими силами подписать запросы и проверить электронные подписи ответов СМЭВ версии 3.0, и о паре интересных нюансов, с которыми пришлось при этом столкнуться.
Здравствуйте!
Может возникнуть вопрос. Почему своими силами? Когда для СМЭВ 3 есть целый Технологический портал, где
- опубликована вся документация и методические указания,
- есть раздел с часто задаваемыми вопросами,
- можно скачать актуальную версию библиотек клиента СМЭВ 3,
- предоставлены примеры полных конвертов сообщений с подписями,
- можно даже проверить онлайн свое сообщение или из примера на соответствие схемам сервиса СМЭВ и на предмет валидности его электронной подписи
Все верно, портал, безусловно, крайне полезный, и всеми его подсказками и инструментами можно и нужно пользоваться, но вот код на Java напишем свой.
По той простой причине, что уже есть собственная информационная система, работающая с форматами электронной подписи XMLDSig, XAdES, в которой применяются библиотеки проекта Apache Santuario, реализующие основные стандарты безопасности для XML. А также библиотеки, входящие в состав КриптоПро JCSP, помимо работы с XML, обеспечивающие API криптографических функций СКЗИ КриптоПро CSP.
Написание собственных методов для работы с электронными подписями СМЭВ 3 в данном случае выглядит более целесообразно, нежели разворачивание полного клиента поставляемого:
ФГБУ НИИ «Восход» (до 21 марта 2016 года ФГУП НИИ «Восход») или интеграция, его отдельных классов и пакетов.
В то же время заглянуть в открытый код клиента всегда полезно, а его наличие само по себе говорит о зрелости системы и высоком уровне поддержки.
Анализ исходных данных
Загружаем с портала СМЭВ 3:
Если уже умеем формировать обычный XMLDSig или подписывать, например, конверты сообщений СМЭВ 2, то больше всего начинает интересовать, чем же отличается конверт с подписью СМЭВ 3 от СМЭВ 2.
Открываем пример конверта СМЭВ 3 SendRequestRequestNoAttach.xml
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1">
<S:Body>
<ns2:SendRequestRequest xmlns:ns3="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/faults/1.1" xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1" xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1">
<ns:SenderProvidedRequestData Id="SIGNED_BY_CONSUMER" xmlns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1" xmlns:ns="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1" xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1"> <ns:MessageID>db0486d0-3c08-11e5-95e2-d4c9eff07b77</ns:MessageID><ns2:MessagePrimaryContent><ns1:BreachRequest xmlns:ns1="urn://x-artefacts-gibdd-gov-ru/breach/root/1.0" xmlns:ns2="urn://x-artefacts-gibdd-gov-ru/breach/commons/1.0" xmlns:ns3="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1" Id="PERSONAL_SIGNATURE"> <ns1:RequestedInformation> <ns2:RegPointNum>Т785ЕС57</ns2:RegPointNum> </ns1:RequestedInformation> <ns1:Governance> <ns2:Name>ГИБДД РФ</ns2:Name> <ns2:Code>GIBDD</ns2:Code> <ns2:OfficialPerson> <ns3:FamilyName>Загурский</ns3:FamilyName> <ns3:FirstName>Андрей</ns3:FirstName> <ns3:Patronymic>Петрович</ns3:Patronymic> </ns2:OfficialPerson></ns1:Governance> </ns1:BreachRequest> </ns2:MessagePrimaryContent> <ns:TestMessage/></ns:SenderProvidedRequestData>
<ns2: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:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/><ds:Reference URI="#SIGNED_BY_CONSUMER"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/><ds:DigestValue>/jXl70XwnttJB5sSokwh8SaVHwo2gjgILSu0qBaLUAo=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>J3746ks34pOcPGQpKzc0sz3n9+gjPtzZbSEEs4c3sTwbtfdaY7N/hxXzEIvXc+3ad9bc35Y8yBhZ/BYbloGt+Q==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIBcDCCAR2gAwIBAgIEHVmVKDAKBgYqhQMCAgMFADAtMRAwDgYDVQQLEwdTWVNURU0xMQwwCgYDVQQKEwNJUzIxCzAJBgNVBAYTAlJVMB4XDTE1MDUwNzEyMTUzMFoXDTE4MDUwNjEyMTUzMFowLTEQMA4GA1UECxMHU1lTVEVNMTEMMAoGA1UEChMDSVMyMQswCQYDVQQGEwJSVTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4BA0MABEDoWGZlTUWD43G1N7TEm14+QyXrJWProrzoDoCJRem169q4bezFOUODcNooQJNg3PtAizkWeFcX4b93u8fpVy7RoyEwHzAdBgNVHQ4EFgQUaRG++MAcPZvK/E2vR1BBl5G7s5EwCgYGKoUDAgIDBQADQQCg25vA3RJL3kgcJhVOHA86vnkMAtZYr6HBPa7LpEo0HJrbBF0ygKk50app1lzPdZ5TtK2itfmNgTYiuQHX3+nE</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></ns2:CallerInformationSystemSignature>
</ns2:SendRequestRequest>
</S:Body>
</S:Envelope>
Дедуктивным методом выясняется что:
- больше не используется прием с выносом из содержимого тега Signature в Security заголовок элемента BinarySecurityToken с сертификатом открытого ключа проверки электронной подписи и ссылкой на него через SecurityTokenReference в теле самого Signature, как, например, в СМЭВ 2.4.6. Теперь сертификат должен находиться внутри Signature.
- второе и, по сути, самое существенное и важное изменение, оказывающее большое влияние на процесс подписи — это добавление новой проприетарной трансформации:
<ds:Transform Algorithm="urn://smev-gov-ru/xmldsig/transform"/>
Через эту трансформацию распространяются собственные правила каноникализации СМЭВ 3.
Каноникализация — процесс приведения данных, имеющих несколько возможных форм представления, к одному нормализованному стандартному виду.
Перед тем как посчитать хэш подписываемого атрибута в XML-конверте и подписать, необходимо выполнить его конвертацию в заданный правилами СМЭВ 3 вид.
В поисках описания трансформации urn://smev-gov-ru/xmldsig/transform открываем Методические рекомендации 3.4.0.3
Знакомимся с пунктом 4.4.2.1 Правила формирования электронной подписи сообщений
Формат подписи XMLDSig detached (https://www.w3.org/TR/xmldsig-core/)
Трансформация, дополнительно к канонизации urn://smev-gov-ru/xmldsig/transform
Требования к форматированию В XML-структуре подписи между элементами не допускается наличие текстовых узлов, в том числе переводов строки.
Пункт Методических указаний 12.4. ПРИЛОЖЕНИЕ 4: ОБРАЗЦОВАЯ РЕАЛИЗАЦИЯ ТРАНСФОРМАЦИИ URN://SMEV-GOV-RU/XMLDSIG/TRANSFORM
содержит Java класс SmevTransformSpi.java, реализующий алгоритм трансформации «urn://smev-gov-ru/xmldsig/transform», наследник org.apache.xml.security.transforms.TransformSpi из библиотеки Apache Santuario.
Таким образом, чтобы обеспечить каноникализацию подписываемого конверта СМЭВ 3, можно использовать в своем коде этот класс трансформации.
Единственным условием и ограничением в этом случае будет, что для обработки XML-документа при формировании подписи или ее проверки нужно использовать именно org.apache.xml.security.signature.XMLSignature из проекта Apache Santuario.
Задействовать инструменты из пакетов javax.xml.crypto.dsig или ru.CryptoPro.JCPxml.xmldsig просто так уже не получится.
Подготовка к подписи по правилам СМЭВ 3
Apache Santuario изначально ничего не знает про ГОСТ криптографические алгоритмы и СКЗИ КриптоПро.
В библиотеке xmlsec-1.5.0.jar в файле \org\apache\xml\security\resource\config.xml содержатся настройки только для работы с зарубежными криптографическими алгоритмами.
Чтобы он начал распознавать и применять ГОСТ, нужно выполнить его инициализацию.
По старинке это делалось так:
//APACHE-SANTUARIO INIT WITH CryptoPro JCP
System.setProperty("org.apache.xml.security.resource.config", "resource/jcp.xml");
org.apache.xml.security.Init.init();
String cfile1 = System.getProperty("org.apache.xml.security.resource.config");
LOGGER.log(Level.INFO, "Init class URL: " + org.apache.xml.security.Init.class.getProtectionDomain().getCodeSource().getLocation());
LOGGER.log(Level.INFO, cfile1);
В новых версиях КриптоПро JCP (JCSP) инициализацию выполнит одна строчка:
ru.CryptoPro.JCPxml.xmldsig.JCPXMLDSigInit.init();
Теперь нужно Apache Santuario научить новым правилам трансформации, которые диктует СМЭВ 3. Для этого регистрируем класс трансформации:
try {
Transform.register(SmevTransformSpi.ALGORITHM_URN, SmevTransformSpi.class.getName());
santuarioIgnoreLineBreaks(true);
LOGGER.log(Level.INFO, "SmevTransformSpi has been initialized");
} catch (AlgorithmAlreadyRegisteredException e) {
LOGGER.log(Level.INFO, "SmevTransformSpi Algorithm already registered: " + e.getMessage());
}
Заодно сразу выполняем требование из Методических указаний:
Требования к форматированию В XML-структуре подписи между элементами не допускается наличие текстовых узлов, в том числе переводов строки.
santuarioIgnoreLineBreaks(true);
private static final String IGNORE_LINE_BREAKS_FIELD = "ignoreLineBreaks";
/**
* Apache Santuario privileged switch IgnoreLineBreaks property
*
* @param mode
*/
private void santuarioIgnoreLineBreaks(Boolean mode) {
try {
Boolean currMode = mode;
AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() {
public Boolean run() throws Exception {
Field f = XMLUtils.class.getDeclaredField(IGNORE_LINE_BREAKS_FIELD);
f.setAccessible(true);
f.set(null, currMode);
return false;
}
});
} catch (Exception e) {
LOGGER.warning("santuarioIgnoreLineBreaks " + ExceptionUtils.getFullStackTrace(e));
}
}
Делается это в привилегированном блоке AccessController.doPrivileged
и через reflection, из-за особенности реализации свойства ignoreLineBreaks в Santuario.
Просто через настройку системного свойства:
System.setProperty("org.apache.xml.security.ignoreLineBreaks", "true");
Через настройку опции JVM:
-Dcom.sun.org.apache.xml.internal.security.ignoreLineBreaks=true
Если взглянуть на код класса org.apache.xml.security.utils.XMLUtils, то можно увидеть, что поле ignoreLineBreaks статическое, инициализируется в привилегированном блоке из системного свойства «org.apache.xml.security.ignoreLineBreaks».
private static boolean ignoreLineBreaks =
AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return Boolean.valueOf(Boolean.getBoolean
("org.apache.xml.security.ignoreLineBreaks"));
}
}).booleanValue();
public static boolean ignoreLineBreaks() {
return ignoreLineBreaks;
}
Такая реализация приводит к невозможности гибко настроить в одном Java процессе для части методов игнорировать перевод строк, а для другой части не игнорировать.
Т.е., если одно приложение выполняет подписи XMLDsig, СМЭВ 2 и СМЭВ 3, все XML документы, обработанные Santuario должны на выходе лишиться перевода строк.
С этим свойством, конечно, возникает вопрос к Apache Santuario:
Подпись сообщений СМЭВ 3
Для подписи документов СМЭВ 3 все готово.
Код подписания выглядит следующим образом:
private static final String XMLDSIG_MORE_GOSTR34102001_GOSTR3411 = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
private static final String XMLDSIG_MORE_GOSTR3411 = "http://www.w3.org/2001/04/xmldsig-more#gostr3411";
private static final String CANONICALIZATION_METHOD = "http://www.w3.org/2001/10/xml-exc-c14n#";
private static final String DS_SIGNATURE = "//ds:Signature";
private static final String SIG_ID = "sigID";
private static final String COULD_NOT_FIND_XML_ELEMENT_NAME = "ERROR! Could not find xmlElementName = ";
private static final String GRID = "#";
private static final String XML_SIGNATURE_ERROR = "xmlDSignature ERROR: ";
try {
// инициализация объекта чтения XML-документа
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// установка флага, определяющего игнорирование пробелов в
// содержимом элементов при обработке XML-документа
dbf.setIgnoringElementContentWhitespace(true);
// установка флага, определяющего преобразование узлов CDATA в
// текстовые узлы при обработке XML-документа
dbf.setCoalescing(true);
// установка флага, определяющего поддержку пространств имен при
// обработке XML-документа
dbf.setNamespaceAware(true);
// загрузка содержимого подписываемого документа на основе
// установленных флагами правил из массива байтов data DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
Document doc = documentBuilder.parse(new ByteArrayInputStream(data));
/*
* Добавление узла подписи <ds:Signature> в загруженный XML-документ
*/
// алгоритм подписи (ГОСТ Р 34.10-2001)
final String signMethod = XMLDSIG_MORE_GOSTR34102001_GOSTR3411;
// алгоритм хеширования, используемый при подписи (ГОСТ Р 34.11-94)
final String digestMethod = XMLDSIG_MORE_GOSTR3411;
final String canonicalizationMethod = CANONICALIZATION_METHOD;
String[][] filters = {{XPath2FilterContainer.SUBTRACT, DS_SIGNATURE}};
String sigId = SIG_ID;
// инициализация объекта формирования ЭЦП в соответствии с
// алгоритмом ГОСТ Р 34.10-2001
XMLSignature sig = new XMLSignature(doc, "", signMethod, canonicalizationMethod);
// определение идентификатора первого узла подписи
sig.setId(sigId);
// получение корневого узла XML-документа
Element anElement = null;
if (xmlElementName == null) {
anElement = doc.getDocumentElement();
} else {
NodeList nodeList = doc.getElementsByTagName(xmlElementName);
anElement = (Element) nodeList.item(0);
}
// = doc.getElementById("#AppData");
// добавление в корневой узел XML-документа узла подписи
if (anElement != null) {
anElement.appendChild(sig.getElement());
} else {
throw new SignatureProcessorException(COULD_NOT_FIND_XML_ELEMENT_NAME + xmlElementName);
}
/*
* Определение правил работы с XML-документом и добавление в узел подписи этих
* правил
*/
// создание узла преобразований <ds:Transforms> обрабатываемого
// XML-документа
Transforms transforms = new Transforms(doc);
// добавление в узел преобразований правил работы с документом
// transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
transforms.addTransform(SmevTransformSpi.ALGORITHM_URN);
// добавление в узел подписи ссылок (узла <ds:Reference>),
// определяющих правила работы с
// XML-документом (обрабатывается текущий документ с заданными в
// узле <ds:Transforms> правилами
// и заданным алгоритмом хеширования)
sig.addDocument(xmlElementID == null ? "" : GRID + xmlElementID, transforms, digestMethod);
/*
* Создание подписи всего содержимого XML-документа на основе закрытого ключа,
* заданных правил и алгоритмов
*/
// создание внутри узла подписи узла <ds:KeyInfo> информации об
// открытом ключе на основе
// сертификата
sig.addKeyInfo(x509Cert);
// создание подписи XML-документа
sig.sign(privateKey);
// определение потока, в который осуществляется запись подписанного
// XML-документа
bais = new ByteArrayOutputStream();
// инициализация объекта копирования содержимого XML-документа в
// поток
TransformerFactory tf = TransformerFactory.newInstance();
// создание объекта копирования содержимого XML-документа в поток
Transformer trans = tf.newTransformer();
// копирование содержимого XML-документа в поток
trans.transform(new DOMSource(doc), new StreamResult(bais));
bais.close();
} catch (TransformationException e) {
throw new SignatureProcessorException("TransformationException " + XML_SIGNATURE_ERROR + e.getMessage());
} catch (XMLSignatureException e) {
throw new SignatureProcessorException("XMLSignatureException " + XML_SIGNATURE_ERROR + e.getMessage());
} catch (TransformerException e) {
throw new SignatureProcessorException("TransformerException " + XML_SIGNATURE_ERROR + e.getMessage());
} catch (IOException e) {
throw new SignatureProcessorException("IOException " + XML_SIGNATURE_ERROR + e.getMessage());
} catch (XMLSecurityException e) {
throw new SignatureProcessorException("XMLSecurityException " + XML_SIGNATURE_ERROR + e.getMessage());
} catch (SAXException e) {
throw new SignatureProcessorException("SAXException " + XML_SIGNATURE_ERROR + e.getMessage());
} catch (ParserConfigurationException e) {
throw new SignatureProcessorException(
"ParserConfigurationException " + XML_SIGNATURE_ERROR + e.getMessage());
}
return bais.toByteArray();
Основными параметрами здесь являются:
byte[] data, // XML сообщение в виде массива байтов
String xmlElementName, // имя элемента в XML вместе с префиксом, в который следует добавить подпись, для СМЭВ-3 в общем случае "ns2:CallerInformationSystemSignature"
String xmlElementID // ID элемента в XML (если присутствует) вместе с префиксом, на который следует поставить подпись, для СМЭВ-3 в общем случае "SIGNED_BY_CONSUMER"
X509Certificate certificate // сертификат открытого ключа проверки подписи
PrivateKey privateKey // закрытый ключ подписи
Проверка подписи сообщения СМЭВ 3
Код проверки подписи выглядит следующим образом:
private static final QName QNAME_SIGNATURE = new QName("http://www.w3.org/2000/09/xmldsig#", "Signature", "ds");
private static final String SIGNATURE_NOT_FOUND = "Signature not found!";
private static final String SIGNATURE_NOT_VALID = "Signature not valid";
private static final String SMEV_SIGNATURE_PASSED_CORE_VALIDATION = "SmevSignature passed core validation";
private static final String VERIFY_SIGNATURE_ON_XML_IO_EXCEPTION = "Verify signature on XML IOException: ";
private static final String VERIFY_SIGNATURE_ON_XML_PARSER_CONFIGURATION_EXCEPTION = "Verify signature on XML ParserConfigurationException: ";
private static final String VERIFY_SIGNATURE_ON_XML_SAX_EXCEPTION = "Verify signature on XML SAXException: ";
private static final String VERIFY_SIGNATURE_ON_XML_XML_SIGNATURE_EXCEPTION = "Verify signature on XML XMLSignatureException: ";
private static final String VERIFY_SIGNATURE_ON_XML_XML_SECURITY_EXCEPTION = "Verify signature on XML XMLSecurityException: ";
private static final String ID = "Id";
boolean coreValidity = true;
try {
DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
bf.setNamespaceAware(true);
DocumentBuilder b = bf.newDocumentBuilder();
Document doc = b.parse(new InputSource(new ByteArrayInputStream(signedXmlData)));
NodeList sigs = doc.getElementsByTagNameNS(QNAME_SIGNATURE.getNamespaceURI(), QNAME_SIGNATURE.getLocalPart());
org.apache.xml.security.signature.XMLSignature sig = null;
sigSearch: {
for (int i = 0; i < sigs.getLength(); i++) {
Element sigElement = (Element) sigs.item(i);
String sigId = sigElement.getAttribute(ID);
if (sigId != null) {
sig = new org.apache.xml.security.signature.XMLSignature(sigElement, "");
break sigSearch;
}
}
throw new XMLSignatureVerificationException(SIGNATURE_NOT_FOUND);
}
org.apache.xml.security.keys.KeyInfo ki = (org.apache.xml.security.keys.KeyInfo) sig.getKeyInfo();
X509Certificate certificate = ki.getX509Certificate();
if (!sig.checkSignatureValue(certificate.getPublicKey())) {
coreValidity = false;
LOGGER.log(Level.INFO, SIGNATURE_NOT_VALID);
} else {
LOGGER.log(Level.INFO, String.format(SMEV_SIGNATURE_PASSED_CORE_VALIDATION));
}
} catch (IOException e) {
throw new XMLSignatureVerificationException(VERIFY_SIGNATURE_ON_XML_IO_EXCEPTION + ExceptionUtils.getStackTrace(e));
} catch (ParserConfigurationException e) {
throw new XMLSignatureVerificationException(VERIFY_SIGNATURE_ON_XML_PARSER_CONFIGURATION_EXCEPTION + ExceptionUtils.getStackTrace(e));
} catch (SAXException e) {
throw new XMLSignatureVerificationException(VERIFY_SIGNATURE_ON_XML_SAX_EXCEPTION + ExceptionUtils.getStackTrace(e));
} catch (org.apache.xml.security.signature.XMLSignatureException e) {
throw new XMLSignatureVerificationException(VERIFY_SIGNATURE_ON_XML_XML_SIGNATURE_EXCEPTION + ExceptionUtils.getStackTrace(e));
} catch (XMLSecurityException e) {
throw new XMLSignatureVerificationException(VERIFY_SIGNATURE_ON_XML_XML_SECURITY_EXCEPTION + ExceptionUtils.getStackTrace(e));
}
return coreValidity;
Проблемы. Хэш не совпадает
Для отладки использовался пример конверта СМЭВ 3 SendRequestRequestNoAttach.xml
Из него был удален элемент ds:Signature с целью подписать сообщение заново и сверить с оригиналом.
Несмотря на то, что метод подписи и трансформация SmevTransformSpi, взятая из Методических указаний, отрабатывали, на выходе был подписанный документ, подпись которого при онлайн-проверке на портале СМЭВ 3 трактовалась как
ЭП-ОВ не подтверждена: Ошибка проверки ЭП: Нарушена целостность ЭП
<ds:DigestValue>e76oVeYGapFDE+PV6glsj0XDjLHydLMd0cSkFPY8fWk=</ds:DigestValue>
не совпадал с оригинальным примером:
<ds:DigestValue>/jXl70XwnttJB5sSokwh8SaVHwo2gjgILSu0qBaLUAo==</ds:DigestValue>
Для диагностики причин в класс SmevTransformSpi в метод process был добавлен свой XMLEventWriter.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLEventWriter bdst =
outputFactory.get().createXMLEventWriter(baos, ENCODING_UTF_8);
для параллельного анализа всех этапов трансформации.
Нормализованный элемент XML, на который требуется поставить подпись, выглядел следующим образом:
<ns1:SenderProvidedRequestData xmlns:ns1="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1" Id="SIGNED_BY_CONSUMER"><ns1:MessageID>db0486d0-3c08-11e5-95e2-d4c9eff07b77</ns1:MessageID><ns2:MessagePrimaryContent xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1"><ns3:BreachRequest xmlns:ns3="urn://x-artefacts-gibdd-gov-ru/breach/root/1.0" Id="PERSONAL_SIGNATURE"><ns3:RequestedInformation><ns4:RegPointNum xmlns:ns4="urn://x-artefacts-gibdd-gov-ru/breach/commons/1.0">Т785ЕС57</ns4:RegPointNum></ns3:RequestedInformation><ns3:Governance><ns4:Name>ГИБДД РФ</ns4:Name><ns4:Code>GIBDD</ns4:Code><ns4:OfficialPerson><ns5:FamilyName xmlns:ns5="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1">Загурский</ns5:FamilyName><ns5:FirstName>Андрей</ns5:FirstName><ns5:Patronymic>Петрович</ns5:Patronymic></ns4:OfficialPerson></ns3:Governance></ns3:BreachRequest></ns2:MessagePrimaryContent><ns1:TestMessage></ns1:TestMessage></ns1:SenderProvidedRequestData>
Поиск решения показал, что, во-первых форум КриптоПро, нормализованный документ может выглядеть на самом деле иначе и соответственно его хэш будет другой и возможно правильный.
Во-вторых, привел в GitHub, где был выложен класс SmevTransformSpi более старой версии.
Старая версия класса трансформации выдала следующий нормализованный документ:
<ns1:SenderProvidedRequestData xmlns:ns1="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/1.1" Id="SIGNED_BY_CONSUMER"><ns1:MessageID>db0486d0-3c08-11e5-95e2-d4c9eff07b77</ns1:MessageID><ns2:MessagePrimaryContent xmlns:ns2="urn://x-artefacts-smev-gov-ru/services/message-exchange/types/basic/1.1"><ns3:BreachRequest xmlns:ns3="urn://x-artefacts-gibdd-gov-ru/breach/root/1.0" Id="PERSONAL_SIGNATURE"><ns3:RequestedInformation><ns4:RegPointNum xmlns:ns4="urn://x-artefacts-gibdd-gov-ru/breach/commons/1.0">Т785ЕС57</ns4:RegPointNum></ns3:RequestedInformation><ns3:Governance><ns5:Name xmlns:ns5="urn://x-artefacts-gibdd-gov-ru/breach/commons/1.0">ГИБДД РФ</ns5:Name><ns6:Code xmlns:ns6="urn://x-artefacts-gibdd-gov-ru/breach/commons/1.0">GIBDD</ns6:Code><ns7:OfficialPerson xmlns:ns7="urn://x-artefacts-gibdd-gov-ru/breach/commons/1.0"><ns8:FamilyName xmlns:ns8="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1">Загурский</ns8:FamilyName><ns9:FirstName xmlns:ns9="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1">Андрей</ns9:FirstName><ns10:Patronymic xmlns:ns10="urn://x-artefacts-smev-gov-ru/supplementary/commons/1.0.1">Петрович</ns10:Patronymic></ns7:OfficialPerson></ns3:Governance></ns3:BreachRequest></ns2:MessagePrimaryContent><ns1:TestMessage></ns1:TestMessage></ns1:SenderProvidedRequestData>
С ним хэш стал совпадать, а подпись успешно проходить валидацию.
Сравнение версий класса SmevTransformSpi показала, что помимо добавленных в новой реализации дополнительных функций логирования и диагностики в debug режиме:
if (logger.isDebugEnabled()) {
debugStream = new DebugOutputStream(argDst);
dst = outputFactory.get().createXMLEventWriter(debugStream, ENCODING_UTF_8);
} else {
dst = outputFactory.get().createXMLEventWriter(argDst, ENCODING_UTF_8);
}
Класс из Методических указаний не содержит нужную строчку, или содержит опечатку:
prefixMappingStack.pop();
, которая удаляет первый объект из стека с префиксами
Stack<List<Namespace>> prefixMappingStack = new Stack<List<Namespace>>();
, что приводило к неверной работе SmevTransformSpi.
Добавление этой строки в новую версию SmevTransformSpi.java решило проблему.
Работающий класс трансформации и конверт с подписью можно посмотреть в github.com/VBurmistrov/Smev3
Результаты
Подписание конвертов СМЭВ 3 выполняется успешно.
Сообщения проходят проверку на портале Электронного правительства Госуслуги
И в собственном приложении:
17 апреля 2022, 23:29 /
Брокеров лишили возможности проверять паспорта клиентов через Минцифры
У некоторых игроков возникли проблемы с открытием новых счетов
Проведение удаленной идентификации с использованием сервиса УПРИД по набору данных последние несколько лет было основным способом для брокеров-НФО и управляющих компаний заключить договор онлайн / Максим Стулов / Ведомости
Финансовые организации лишили возможности проверять паспорта новых клиентов через Минцифры в едином сервисе упрощенной идентификации системы межведомственного электронного взаимодействия (СМЭВ). Письмо с указанием отключить от использования сервиса все организации, кроме «Почта банка», 7 апреля зампред правительства Татьяна Голикова направила министру цифрового развития, связи и массовых коммуникаций Максуту Шадаеву. «Ведомости» ознакомились с копией документа, в Минцифры подтвердили соответствующее решение.
Отключение от системы привело к проблемам с открытием счетов новым клиентам у некоторых крупных брокеров. «Открытие новых счетов с учетом текущих проблем очень сложное, мы испытываем сложности с работой СМЭВ», – говорит представитель «Открытие инвестиций». Проблему подтверждает и представитель брокера БКС.
СМЭВ – государственная система, с помощью которой все ведомства обмениваются документами в электронном виде внутри единого информационного канала. В системе финансовым организациям доступен единый сервис упрощенной идентификации (УПРИД). Через этот сервис можно проводить упрощенную идентификацию и проверку введенных данных: ФИО, серии и номера паспорта, ИНН, СНИЛСа. Внешний потребитель, например брокер, МФО или банк, может подключиться к СМЭВ УПРИД, заключив договор.
В начале апреля МВД в одностороннем порядке отключило Минцифры от сервиса, с помощью которого Минцифры проверяло соответствие ФИО и паспорта гражданина, получая сведения от брокера и УК через УПРИД, сделав таким образом использование сервиса УПРИД невозможным для проведения удаленной идентификации, объясняет вице-президент НАУФОР Екатерина Андреева.
Проведение удаленной идентификации с использованием сервиса УПРИД по набору данных последние несколько лет было основным способом для брокеров-НФО и управляющих компаний заключить договор онлайн, говорит Андреева. По оценкам НАУФОР, только за 2021 г. общее количество инвесторов, заключивших брокерский договор таким способом, составило 1,6–1,7 млн человек.
Все брокеры теперь должны осуществлять упрощенную идентификацию клиентов через СМЭВ напрямую с МВД, ПФР и ФНС – сейчас это условие выполняют не все организации, объясняет представитель Минцифры. Отсутствие у брокеров доступа к сервису тем не менее не означает, что их новые клиенты не смогут открыть счета дистанционно: брокерам необходимо завершить переход на работу с сервисами государственных органов напрямую, заключает он.
«Почта банку» продлен доступ к системе до 1 июня, следует из письма. Как пояснил представитель Минцифры, такая временная привилегия связана с тем, что банк выпускает «Пушкинскую карту». Эти два месяца даются банку на технический переход, который необходим для работы социального проекта, подчеркнули в министерстве.
СМЭВ УПРИД – не единственная система для удаленной идентификации клиентов. Второй возможный путь проверки данных клиента – через портал «Госуслуги», доступ к которому имеют зарегистрированные в Единой системе идентификации и аутентификации (ЕСИА) граждане.
СМЭВ удобнее для клиента с точки зрения того, что организация самостоятельно проверяет данные через собственные программы, объясняет «Ведомостям» собеседник в крупном брокере. На сайте госуслуг гражданину для доступа ко всем электронным услугам необходимо иметь подтвержденную учетную запись – сделать это можно лично с паспортом в банке либо, например, в МФЦ или же онлайн через приложение одного из 10 банков (но при условии, что пользователь – клиент банка).
Несмотря на сохраняющуюся возможность использовать подтвержденную запись ЕСИА для прохождения удаленной идентификации, невозможность использовать УПРИД является существенным барьером для прихода на рынок новых частных инвесторов и выполнения предусмотренных законодательством процедур обновления сведений об уже существующих клиентах, отмечает Андреева.
Последние два месяца сайт госуслуг перегружен, что увеличивает время ожидания, говорит собеседник «Ведомостей» в одном из брокеров. Кроме того, процесс оформления счетов растянется, так как для его открытия клиенту надо иметь полностью подтвержденную учетную запись на «Госуслугах», а это приведет к росту числа недовольных клиентов.
В ФГ «Финам» не используют УПРИД в работе, говорит руководитель управления финансового мониторинга компании Александр Колпащиков. При удаленном открытии счетов брокер использует СМЭВ только для подтверждения ИНН клиента, остальные проверки проводятся с помощью других сервисов. Поэтому на скорости удаленного оформления новых клиентов изменения не отразятся, замечает Колпащиков, – подтвердить действительность паспорта брокер сможет напрямую через профильный сервис МВД. Проверка ИНН в ФНС и СНИЛСов в ПФР на данный момент по-прежнему доступна в СМЭВ напрямую, говорит он.
Представители Голиковой, МВД, «Почта банка», «Тинькофф инвестиций» и «ВТБ инвестиций» не ответили на запрос «Ведомостей».
Система исполнения регламентов
Назначение СИР — автоматизация процессов предоставления государственных и муниципальных услуг гражданам и организациям (Заявителям) по заявлениям, поступающим с Портала Государственных услуг, а также, при личном обращении Заявителей в РОИВ, ОМСУ и в подведомственные им учреждения; регламентированное взаимодействие между различными РОИВ и ОМСУ и иными информационными системами, с использованием системы межведомственного электронного взаимодействия (СМЭВ).
Описание систем исполнения регламентов
Руководство пользователя СИР 3.0
Состав процедур, необходимых для обеспечения возможности работать в СИР и последовательность их выполнения описаны в документе «Технологическая карта процесса подготовки и предоставления услуг РОИВ и ОМСУ»
Порядок действий пользователей СИР по настройке рабочих мест с переходом на аутентификацию через ЕСИА
1. Настройка ПК пользователя.
- Зарегистрировать себя, как физическое лицо на сайте ЕСИА https://esia.gosuslugi.ru, согласно Инструкции по переходу на аутентификацию с использованием ЕСИА. Результатом регистрации должно быть получение подтвержденной учетной записи физ. лица в ЕСИА
- Уполномоченный сотрудник ведомства, к которому относится Пользователь (руководитель или администратор), должен выполнить в ЕСИА процедуру присоединения сотрудника к органу власти (ведомству) — см. Инструкции по переходу на аутентификацию с использованием ЕСИА
- Направить заявку на [email protected] на создание учетной записи пользователя в СИР по своему СНИЛС, либо выпуск сертификата доступа к системе, в том случае, если ранее Пользователь не работал в СИР. Если Пользователь имел сертификат доступа к СИР, то проверить срок его действия. Если закончился, то направить заявку на [email protected] на продление этого сертификата (чтобы сохранить все настройки пользователя в СИР).
- Получив ответ от техподдержки о создании учетной записи пользователя СИР, либо сертификат доступа к системе, новый Пользователь должен направить заявку на [email protected] на настройку его СНИЛС, либо сертификата, на какие-то виды настроек: для работы с МФЦ, для настройки на АРМ МВ, для настройки на тиражируемые услуги ЛАНИТ и АТК, на АРМ–Поставщика и др.
- Направить на [email protected] Заявку на изменение пользователей СНИЛС
3. Порядок входа Пользователя в СИР по окончании настроeк
- Открыть браузер Mozilla Firefox, и очистить в нем КЭШ и КУКи
- Ввести в адресную ссылку https://66.sir.egov.local/tp-manager/
- Подтвердить выбор своего сертификата, если система предложит — выполнится переход на ЕСИА автоматически
- Подтвердить себя в ЕСИА. Подтвердить выбор своего сертификата, если система предложит. Выполнится переход на СИР автоматически.
<!–
–>
R-Style Softlab объявила о появлении в составе линейки RS-Connect для автоматизации взаимодействия с государственными информационными системами нового модуля — «RS-Connect. Проверка паспорта на действительность».
Модуль позволяет банку через внешнюю систему СМЭВ 3 автоматически осуществлять проверку паспортов клиентов — физических лиц по базе МВД, а по недействительным паспортам получать информацию о причинах недействительности.
Эта базовая проверка должна выполняться в каждом банке. Раньше для этого использовалась СМЭВ 2, но в настоящее время регулятор последовательно отключает ее сервисы и переносит их в СМЭВ 3. Именно поэтому компания-разработчик реализовала взаимодействие через СМЭВ 3.
Артем Пермяков, Directum: HR-специалист становится агентом цифровизации
Работает новый модуль следующим образом: получает из систем банка запросы на проверку; отправляет эти запросы и получает ответ из МВД через СМЭВ 3; пересылает полученный ответ в системы банка.
«Проверка паспорта на действительность — небольшая, но очень важная часть любого банковского процесса, связанного с обслуживанием клиентов. Подключение к сервису СМЭВ 3 по проверке паспорта позволяет банку быстро определить, всё ли хорошо с паспортом клиента. Автоматический режим выполнения данного процесса не только минимизирует ошибки ручного ввода, но и защищает банк от недостоверных документов клиента», — сказала Анна Назарова, заместитель директора департамента банковского ПО RS-Bank по развитию.