СМЭВ 3 ЧТО ЭТО ТАКОЕ

СМЭВ 3 ЧТО ЭТО ТАКОЕ ЭЦП

Общая схема взаимодействия через СМЭВ

Время на прочтение

В цикле статей мы, команда Gems Development, расскажем о работе с «Госуслугами» по ту сторону экрана и о том, как оформить эффективное взаимодействие органов государственной власти с порталом.

Что такое СМЭВ

СМЭВ — это тот транспорт, которым доставляются миллионы «конвертов», необходимых для оказания госуслуг. Через СМЭВ обмениваются информацией между собой:

  • федеральные и региональные ведомства

  • Единая система идентификации и аутентификации (ЕСИА)

  • ряд коммерческих организаций

СМЭВ в цифрах:

Трафик СМЭВ, количество подключённых систем, скорость и безотказность
Трафик СМЭВ, количество подключённых систем, скорость и безотказность

Актуальных СМЭВ два: СМЭВ3 и СМЭВ4. При этом четвёртая версия не заменяет третью. Это две принципиально разные системы с одним предназначением — организация обменов между системами участников взаимодействия. Разница в том, что:

  • СМЭВ3 подходит, когда нужно гарантированно передать информацию

  • СМЭВ4 — когда на первом месте стоит скорость обмена данными

В этой статье речь пойдёт о третьей версии СМЭВ. Как ни крути, она пока остаётся наиболее востребованной. Однако популярность четвёртой растёт на глазах, и о ней я планирую написать в следующей статье.

Время на прочтение

Привет ИТ-сообщество! Я Анастасия Пятько, аналитик-внедренец из РТЛабс. Это компания, которая развивает всем известные Госуслуги и пытается облегчить нашу бюрократическую жизнь.

СМЭВ 3 ЧТО ЭТО ТАКОЕ

Недавно мне довелось выступить на HighLoad++ 2022 с похожей темой: «СМЭВ. Сильно проще, чем кажется. Полезные советы, как стартовать интеграцию через СМЭВ3 и СМЭВ4». Организаторы знают своё дело. В зале была заинтересованная аудитория, которая задавала вопросы с неподдельным интересом. С некоторыми разговор у стенда продолжался ещё несколько часов. Так родилась идея — зафиксировать всё текстом в этой статье.

Начнём с небольшой предыстории. Цифровизация пришла в нашу большую страну определённо раньше того, как появились эксперты, которые смогли бы сразу сказать, как надо делать, придумали стандарты и протоколы. Регионы, ведомства, их подрядчики писали свои системы на разных языках программирования, строя различную архитектуру, а потом делали интеграции как получится. В какой-то момент систем стало много. Пришло понимание, что обмениваться информацией между собой без единого унифицированного фреймворка им стало просто невозможно. И вот 12 лет назад появилась Система межведомственного электронного взаимодействия (СМЭВ).

Время на прочтение

СМЭВ 3 ЧТО ЭТО ТАКОЕ

Система межведомственного электронного взаимодействия (СМЭВ) задумывалась как цифровая среда предоставления услуг и исполнения государственных и муниципальных функций в электронной форме.

В настоящее время СМЭВ продолжает расширять свои возможности и вовлекать все большее количество участников взаимодействия.

Что оказалось как нельзя кстати, в том числе для коммерческих организаций, в частности банков, которые все больше стремятся перевести свои услуги в цифру и сериализовать процессы.

В этой статье мы поговорим о том, как своими силами подписать запросы и проверить электронные подписи ответов СМЭВ версии 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

Для подписи документов СМЭВ 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 ЧТО ЭТО ТАКОЕ

Для отладки использовался пример конверта СМЭВ 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);
            }
  
  

Класс из Методических указаний не содержит нужную строчку, или содержит опечатку:

ЭЦП:  CRYPTOPRO ДЛЯ LESEGAIS И ОШИБКА ДОСТУПА К УТИЛИТЕ EGAIS CRYPTO LESEGAIS

СМЭВ 3 ЧТО ЭТО ТАКОЕ

   prefixMappingStack.pop();  
  

, которая удаляет первый объект из стека с префиксами

     Stack<List<Namespace>> prefixMappingStack = new Stack<List<Namespace>>();  
  

, что приводило к неверной работе SmevTransformSpi.

Добавление этой строки в новую версию SmevTransformSpi.java решило проблему.

Работающий класс трансформации и конверт с подписью можно посмотреть в github.com/VBurmistrov/Smev3

Результаты

Подписание конвертов СМЭВ 3 выполняется успешно.

Сообщения проходят проверку на портале Электронного правительства Госуслуги

СМЭВ 3 ЧТО ЭТО ТАКОЕ

И в собственном приложении:

СМЭВ 3 ЧТО ЭТО ТАКОЕ

Как работает СМЭВ3

Собственно, все сообщения в СМЭВ3 — это XML, составленные на основе XSD-схем самого транспорта и вида сведения, отправленные через веб-сервис.

По опыту предыдущих уже неактуальных версий системы в СМЭВ3 сделан упор на гарантии доставки. То есть «доставить любой ценой», несмотря на возможные технические проблемы на стороне любого из участников взаимодействия, — лозунг третьей СМЭВ.

Что такое очереди в СМЭВ3

Важная фишка СМЭВ3 — очереди. В самом транспорте для каждой зарегистрированной системы создаются как минимум 2 очереди: запросов и ответов.

Системы всех участников должны уметь формировать сообщения и подписывать их зарегистрированным сертификатом. Сообщения бывают трёх типов:

  • send — с основной информацией

  • get — для опроса очередей

  • ack — для подтверждения получения

Рассмотрим обмен между информационными системами двух ведомств, одна из которых инициирует обмен или запрашивает информацию, вторая — отвечает на запрос.

1. Инициатор отправляет запрос
—SendRequest. Он попадает в очередь запросов ответчика. Там запрос будет храниться до тех пор, пока ответчик его не вычитает, но максимум — 14 дней.

Если за 14 дней запрос не вычитают, инициатору придёт «отбивка» от СМЭВ, что его запрос попал в архив.

2. Ответчик опрашивает очередь
— GetRequest. Он должен делать это постоянно. И когда туда попадает запрос, ему возвращается непустой «конверт».

3. Ответчик обрабатывает запрос.
Получив «конверт», система ответчика должна выполнить ряд действий: распарсить, уложить в базу и т. п. Затем система отправляет в СМЭВ «конверт» с подтверждением получения запроса — AckRequest. Это ещё один уровень для обеспечения гарантированной доставки. Если СМЭВ не получит от ответчика такое подтверждение, через 15 минут запрос снова вернётся в очередь.

4. Инициатор получает ответ.
После того как система ответчика подготовит «конверт» с ответом, происходит всё ровно то же самое:

  • «конверт» попадает в очередь инициатора — SendResponse

  • инициатор его вычитывает — GetResponse

  • инициатор оправляет подтверждение о получении — AckResponse

Только тогда обмен считается завершённым.

Конечно, здесь ещё много нюансов:

  • существуют другие типы обменов, например рассылка

  • на стороне СМЭВ происходят различные проверки

  • формируются разные типы сообщений: статусные и об ошибках

Но в целом все обмены через СМЭВ3 устроены так, как я описала выше.

Что такое виды сведений в СМЭВ

Важную роль в СМЭВ3 играют такие сущности, как «Виды сведений» (ВС).

Схемами транспорта задаются условно-общие поля для всех обменов, например, для правильной маршрутизации, передачи вложений, подписи и т. п.

Схемами ВС задаются правила, по которым будет формироваться смысловая часть «конверта». То есть как раз та информация, ради которой и осуществляется обмен.

В итоге ВС представляют собой:

  1. Правила, по которым формируются запросы и ответы (XSD).

  2. Эталоны (XML) — примеры «конвертов» для работы эмулятора.

  3. Руководство пользователя — документ, составленный автоматически или вручную владельцем или создателем ВС, призванный помочь подключающимся участникам.

Виды сведений в СМЭВ3
Виды сведений в СМЭВ3

ВС в целом может создать и зарегистрировать любой участник взаимодействия. Таких ВС сейчас около 2 750.

Как подключиться к СМЭВ3

Чтобы стать участником взаимодействия, организации нужно пройти 7 шагов.

  1. Оформить заявку на регистрацию организации в СМЭВ. В заявке указывают нормативно-правовое обоснование подключения. В зависимости от типа организации и её целей, эту заявку могут рассмотреть либо очень быстро, либо долго — с выносом на президиум специальной комиссии.

  2. Организовать защищённый канал. Это также делается по заявке, в рамках которой вам предоставят и помогут настроить оборудование.

  3. Получить сертификаты аккредитованного удостоверяющего центра (АУЦ).

  4. Зарегистрировать одну или несколько своих систем с полученными сертификатами в СМЭВ через Личный кабинет участника взаимодействия (ЛК УВ). Выбрать вид сведения, по которому будете работать, или зарегистрировать свой.

  5. Настроить или разработать интеграционный модуль для подключения к СМЭВ. Здесь вам на помощь придёт наш адаптер СМЭВ3.

  6. Получить доступ к ВС, пройдя процедуру технической готовности (ПТГ) на тестовой среде через ЛК УВ.

  7. Переключиться на продуктивную среду.

Как устроен ЛК УВ

Если первые 3 шага инструкции более или менее понятны, то про остальные хотелось бы рассказать подробнее.

Есть у нас потрясающий ЛК УВ

. Получить к нему доступ не составит труда, если выполнена заявка из первого пункта. Авторизация происходит под учётной записью ЕСИА. Единственное, администратору профиля вашей организации в ЕСИА нужно будет вас присоединить к организации.

Так выглядит ЛК УВ
Так выглядит ЛК УВ

В ЛК УВ автоматизированы все регламентированные процедуры, которые необходимо выполнить для полноценной работы в СМЭВ.

В несколько кликов можно:

  • поменять ей сертификат

  • получить доступ к ВС

  • зарегистрировать свой ВС

  • пройти ПТГ с эмулятором

  • проверить наполненность своих очередей

  • отследить судьбу обмена

  • сформировать отчёт и многое другое

ЛК УВ развивается семимильными шагами и завоёвывает сердца наших пользователей. Особенно рады те, кто знает, как было до его появления. Знаете, мы как-то считали: получилось, что ЛК УВ экономит участникам годы (!) жизни.

Среды в СМЭВ3

В СМЭВ3 мы предоставляем 3 среды: разработки, тестовую и продуктивную.

Среды в СМЭВ3
Среды в СМЭВ3

Среда разработки.
Она даёт уникальную возможность — попробовать свои силы в СМЭВ, не имея ещё ни одного доступа и не дожидаясь выполнения первых пунктов.

На среде разработки можно создать демоверсию организации, зарегистрировать для неё пару систем, вид сведений и попробовать совершить обмены через СМЭВ.

Тестовая среда.
Более популярна, чем среда разработки, потому что сюда перед выходом на прод надо обязательно попасть всем. А большинство поддерживают работоспособность своих тестовых систем и после выхода на прод.

Для тестовой среды и среды разработки не нужен защищённый канал. Опять же получается, что тестироваться можно параллельно с организацией канала для прода.

Ещё одна важная штука для этих сред — сертификат для систем можно сгенерировать прямо в ЛК УВ за несколько секунд.

На тестовой среде помимо её прямого назначения, также проходится ПТГ для получения доступа к видам сведений.

Собственно, ПТГ — это полноценный обмен вашей системы в желаемой роли с нашим эмулятором
Собственно, ПТГ — это полноценный обмен вашей системы в желаемой роли с нашим эмулятором

Продуктивная среда.
Здесь экспериментировать уже нежелательно. Доступна она только через защищённый канал. Конверты подписывать можно только сертификатами, полученными в АУЦ.

Интеграционный узел адаптера (ИУА) СМЭВ3

Лирическое отступление: любовь к аббревиатурам в нашей компании и госсекторе в принципе неспроста. У систем такие названия, чтобы можно было их однозначно идентифицировать. Вот так и с ИУА. Конечно, его любят называть просто «адаптер», но это вызывает недопонимание. Адаптерами подрядчики могут обозвать модули своих систем, а у кого-то разработаны и свои универсальные адаптеры СМЭВ. В СМЭВ4 адаптер — это вообще часть другого ПО.

Итак, ИУА СМЭВ3 — это клиентское ПО, поддерживающее все необходимые операции для выполнения обменов через СМЭВ3. Он разворачивается на стороне участника взаимодействия и предоставляет удобные для интеграции интерфейсы.

По сути, это прослойка между вашей системой и СМЭВ, которая облегчит вам жизнь в несколько раз.

ИУА можно поставить как на Windows, так и на Linux. Есть версия для кубера, а есть для домохозяйки: «далее, далее, ок, готово». Также имеется версия в комплекте со всем необходимым окружением: Java, криптопровайдер и СУБД.

Так выглядит интерфейс адаптера
Так выглядит интерфейс адаптера

Чем же поможет ИУА

  • Возьмёт на себя заботы с подписанием конвертов

  • Будет опрашивать ваши очереди, выполняя get с заданной вами частотой

  • Поможет удобно логировать все обмены

  • Позволит выбрать удобный интерфейс: amqp, rest api, soap, БД, через файловую систему и даже встроенный веб-интерфейс. Используя последний, кстати, можно вообще не разрабатывать свою информационную систему, а пользоваться только адаптером СМЭВ3

  • Сам подберёт конфигурацию для выбранной среды, обернёт в нужный формат передаваемые вложения, отправит статистику и т. д.

ЭЦП:  «Лицензия СКЗИ «Крипто Про CSP» истекла» | Техподдержка Онлайн

ИУА распространяется свободно, и мы настоятельно рекомендуем его использовать всем участникам взаимодействия.

Участники взаимодействия

Представим, что «Госуслуги» — это магазин, на витрине которого представлены сервисы для граждан и организаций. Запрос «покупателя» на услугу передаётся соответствующим органам через систему межведомственного электронного взаимодействия
(СМЭВ). Система передаёт сообщения между порталом и ведомством.

Работа через СМЭВ происходит по протоколу SOAP ( Simple Object Access Protocol
— простой протокол для доступа к объектам).

image

Участники взаимодействия, как в магазине, делятся на поставщиков и потребителей. Поставщик — это информационная система (ИС), которая предоставляет сведения по запросу, а потребитель — система, запрашивает сведения.

Одна и та же ИС может действовать сразу в двух ролях. Например, в процессе предоставления услуги нужно уведомить портал о смене её статуса. В этом случае ИС-поставщик исполняет роль потребителя — проводит информационный обмен по статусам.

Где почитать подробнее и куда бежать с вопросами

Единая система контекстной справки

Как любые уважающие себя системы, наши СМЭВ, ЛК УВ и ИУА, конечно же, обросли официальной документацией. Много страниц сложно читаемого текста.

Но также у нас есть классная база знаний в виде статей. Называется она Единая система контекстной справки
(ЕСКС). Также здесь хранятся официальные документы и дистрибутивы. А ещё есть крайне полезный новостной раздел и форум.

База знаний СМЭВ3
База знаний СМЭВ3

Бот. Судьба сообщения и уведомления

Команда ЛК УВ совместно с другими, внешне не видимыми, но не менее значимыми командами разработали телеграм-бота

. С ним можно общаться о судьбе своих обменов и получать уведомления о ключевых событиях, касающихся вас в СМЭВ.

Есть у нас официальный канал связи с эксплуатацией и другими участниками взаимодействия — Ситуационный центр. Там вам ответят здорово и красиво, но не очень быстро.

Однако мы любим наших пользователей, поэтому часто создаём чаты оперативной поддержки в Telegram. Порой они живут годами, а мы с участниками становимся друг другу родными.

Идя в ногу со временем, мы активно ведём телеграм-канал «Новости СМЭВ+»

. Здесь вы можете не только узнать последние новости, но и задать под любой из них свой вопрос. Неважно, если он будет не в тему новости, — мы ответим!

СМЭВ 3 ЧТО ЭТО ТАКОЕ

СМЭВ — это сложная высоконагруженная система. Но мы очень стараемся, чтобы она казалась лёгкой для пользователей, особенно на самом сложном шаге — этапе подключения к ней.

Это всё, что хотелось бы рассказать. Надеюсь на ваш интерес и мотивацию к написанию новых статей.

Благодарю за внимание.

Редактор: Ольга Кочкина

Виды сведений

Участники обмениваются данным через виды сведений
( протоколы обмена
) — правила формирования пакетов данных для передачи от одного участника другому.

Хороший пример вида сведений — Всероссийская перепись населения 2020
. Данные о переписи передают федеральным органам исполнительной власти в электронном виде. В полученных данных существует чёткая структура сведений: ФИО, пол, дата рождения, гражданство, семейное положение. Также в рамках вида сведений описан ответ, который должен быть получен, если обработка запроса прошла успешно.

На июнь 2020 года в СМЭВ зарегистрировано более 1000 промышленных (рабочих) и 2000 тестовых видов.

Обмен данными в промышленной среде по всем видам сведений ведётся через защищённые каналы связи. Все передаваемые данные сопровождаются электронной цифровой подписью, с помощью которой СМЭВ идентифицирует участников взаимодействия.

Данные передаются по протоколу SOAP, при этом каждое сообщение представляет собой вложенную структуру:

image

Виды сведений делятся на две группы — простые
и универсальные
. Рассмотрим схему обмена данными по простому виду сведений:

image

На схеме видно, что данные форм отображаются непосредственно в конверты обмена данными. Из-за этого появляется ограничение: необходимо разработать структуру блока данных, запроса/ответа для каждого такого вида сведений.

Обмен по универсальному виду сведений можно представить так:

image

На первый взгляд схема может показаться более сложной, однако она демонстрирует принципиальную разницу, которая в итоге упрощает взаимодействие между участниками по универсальному виду сведений (УВС). Специфические данные форм передаются во вложении к конверту СМЭВ, а признаки УВС, позволяющие идентифицировать вид сведений, передаются непосредственно в конверте и имеют одинаковую для любого ВС структуру:

  • номер заявления портала и сведения, позволяющие определить услугу;
  • целевое подразделение, к которому пользователь обращается за услугой.

Данные формы
, заполненные пользователем портала, пакуются во вложение к основному сообщению.

Таким образом можно оформить предоставление практически любых услуг без необходимости проходить трудную регистрацию нового вида сведений.

Постановка задачи

С учётом приведённых выше особенностей, нашей команде предстояло обеспечить интеграцию ИС заказчика с «Госуслугами» по универсальному виду сведений
. Информационная система заказчика — ИАС «Градоустройство»
. С её помощью пользователи ведомств, ответственные за оказания услуг, могут собирать пакеты документов и формировать результаты для дальнейшей передачи на портал через СМЭВ.


Итак, СМЭВ, как в поговорке про слова в песне, нельзя исключить из решения задачи интеграции с порталом государственных услуг. Но это к лучшему: благодаря системе у всех участников есть универсальная среда взаимодействия. Это позволяет опираться на определённый стандарт и не изобретать велосипед.

В следующих статьях мы рассмотрим, как на стороне поставщика сведений организовать обработку заявлений по данным пользователя с использованием движка автоматизации бизнес-процессов Workflow Core.

Очереди сообщений и процесс взаимодействия

В процессе взаимодействия сообщения помещаются в очереди входящих запросов и очереди входящих ответов
. По сути очереди — это контейнеры, в которых содержатся сообщения по видам сведений.

Взаимодействие с очередями происходит с помощью специальных запросов. Более подробно они описаны в методических рекомендациях
по работе со СМЭВ. Отметим только то, что благодаря очередям становится возможным асинхронный обмен данными: потребитель может оставить заявку на получение сведений, а поставщик — разместить ответ.

Следует помнить: чтобы забрать сообщение из очереди, необходимо подтвердить его получение с помощью Ack-запроса. В противном случае СМЭВ посчитает сообщение недоставленным и вернёт его в очередь через 15 минут после извлечения.

image

На каждый запрос может поступить как успешный, так и неуспешный ответ.

Представим себя в роли поставщика сведений: по запросу мы выдаём пользователю градостроительный план земельного участка, причём в рамках нашего ведомства действуют несколько территориальных подразделений, некоторые из которых такую услугу вовсе не оказывают. Допустим, пользователь портала при формировании заявления на получение услуги указал подразделение, не оказывающее услугу. Такая ситуация может возникнуть по двум причинам:

  • Произошло расхождение справочных данных на портале и у поставщика;
  • Нужного соответствия просто нет в настройках системы поставщика.

В любом случае поставщик должен ответить на запрос так, чтобы принимающая сторона могла понять, что запрос завершился неудачно, и, возможно предпринять ответные действия. Ответ на такой запрос оформляется в специальном пакете данных со сведениями о причине отказа.

Успешный ответ предполагает сценарий, в котором результат услуги — это набор файлов (что бывает довольно часто). Перед отправкой результата необходимо выгрузить файлы в файловое хранилище СМЭВ на основе FTP-сервера. Названия файлов и их контрольные суммы нужно зафиксировать в пакете, который отправляем через SOAP. Таким образом, есть две операции по передачи данных, которые нужно связать общим контекстом — сведениями о файлах.

На практике встречаются случаи, когда во время взаимодействия СМЭВ находится в режиме обслуживания, и запросы участника оборачиваются неудачей и требуют повторной отправки. Неудачу нужно зафиксировать и отправить запрос повторно.

Оцените статью
ЭЦП64
Добавить комментарий