Как выполнить интеграцию с веб-сервисом ГИИС ДМДК и подписать SOAP-сообщения электронной подписью в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей
← На главную

При необходимости интеграции системы 1С с государственным информационным интегрированным сервисом ДМДК (ГИИС ДМДК) одной из ключевых и часто сложных задач является корректное подписание SOAP-сообщений электронной подписью. Это требует специфических знаний как в области работы с веб-сервисами, так и в применении криптографических средств в среде 1С. В данной статье мы подробно рассмотрим различные подходы и примеры кода, которые помогут вам успешно реализовать эту интеграцию.

Общие принципы подписания SOAP-сообщений с использованием XMLDSig

Интеграция с ГИИС ДМДК предполагает использование формата XML Digital Signature (XMLDSig) для подписи XML-документов, в том числе SOAP-сообщений. Электронная подпись, как правило, размещается в секции Header SOAP-сообщения. Критически важно подписывать определенные части сообщения, чаще всего именно Body, а не весь SOAP-конверт целиком. Тело сообщения должно содержать атрибут Id, чтобы на него можно было сослаться в подписи. Процесс создания подписи включает в себя следующие шаги:

  1. Формирование базового SOAP-сообщения.
  2. Заполнение Body необходимыми данными и добавление атрибута Id.
  3. Подготовка структуры Security, которая будет содержать подпись.
  4. Вставка сформированной структуры Security в Header SOAP-сообщения.

Для корректного взаимодействия с государственными сервисами, такими как ГИИС ДМДК, часто требуется использовать специфический алгоритм канонизации СМЭВ: urn://smev-gov-ru/xmldsig/transform. Этот алгоритм трансформации обеспечивает единообразное представление XML-документа перед подписанием, что жизненно важно для успешной проверки подписи. Выбор алгоритмов хеширования и подписи (например, ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012) также должен соответствовать требованиям ГИИС ДМДК.

Решение 1: Использование компоненты "КомпонентаXMLDSig" из БСП

В платформе 1С для работы с криптографией и электронными подписями широко используются внешние компоненты. Компонента "КомпонентаXMLDSig", упомянутая в обсуждении, является частью Библиотеки стандартных подсистем (БСП) и активно применяется в типовых конфигурациях, таких как "Управление торговлей" (УТ) версии 11. Рассмотрим шаги и примеры кода для ее использования.

  1. Получение и подключение компоненты:

    Для начала необходимо получить двоичные данные компоненты из общих макетов и подключить ее. В типовых конфигурациях эти данные часто хранятся в общем макете "КомпонентаXMLDSig".

    
    // Функция для получения и подключения компоненты
    &НаКлиенте
    Функция КомпонентаПодписи()
        КомпонентаДвоичныеДанные = ПолучитьКомпонентуПодписи;
        АдресМакета = ПоместитьВоВременноеХранилище(КомпонентаДвоичныеДанные);
        Если ПодключитьВнешнююКомпоненту(АдресМакета, "XMLDSignAddInSymbolicName", ТипВнешнейКомпоненты.Native) Тогда
            ВнешняяКомпонента = Новый("AddIn.XMLDSignAddInSymbolicName.XMLDSignAddIn");
        Иначе
            УстановитьВнешнююКомпоненту(АдресМакета);
            Если ПодключитьВнешнююКомпоненту(АдресМакета, "XMLDSignAddInSymbolicName", ТипВнешнейКомпоненты.Native) Тогда
                ВнешняяКомпонента = Новый("AddIn.XMLDSignAddInSymbolicName.XMLDSignAddIn");
            Иначе
                Сообщить(ОписаниеОшибки);
                ВнешняяКомпонента = Неопределено;
            КонецЕсли;
        КонецЕсли;
        Возврат ВнешняяКомпонента;
    КонецФункции
    
    // Серверная функция для получения двоичных данных компоненты
    &НаСервере
    Функция ПолучитьКомпонентуПодписи() Экспорт
        Возврат ПолучитьОбщийМакет("КомпонентаXMLDSig");
    КонецФункции
    
  2. Подготовка сертификата:

    Перед подписанием необходимо получить данные сертификата в формате Base64. Обычно сертификаты хранятся в справочниках 1С (например, "Сертификаты ЭЦП") в виде двоичных данных.

    
    // Серверная функция для получения сертификата в Base64 строке
    &НаСервере
    Функция ПолучитьСертификатBase64Строку(Ссылка) Экспорт
        ДанныеСертификата = Ссылка.ФайлСертификата.Получить(); ///Двоичные данные сертификата (Из справочника Сертификаты ЭЦП)
        СтрокаBase64 = Base64Строка(ДанныеСертификата);
        Значение = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
        Значение = СтрЗаменить(Значение, Символы.ПС, "");
        Возврат Значение;
    КонецФункции
    
  3. Подписание данных:

    Теперь, когда компонента подключена и сертификат подготовлен, мы можем использовать метод CMSSign компоненты для подписания данных. Важно правильно передать подписываемые данные, сертификат и указать тип подписи.

    
    // Функция для подписания данных с помощью КомпонентыXMLDSig
    &НаКлиенте
    Функция ПодписатьДанные(Сертификат, Данные, Откреп = Ложь)
        ВнешняяКомпонента = КомпонентаПодписи;
        Если ВнешняяКомпонента = Неопределено Тогда
            Возврат Неопределено;
        КонецЕсли;
    
        СертификатКриптографииBase64 = ПолучитьСертификатBase64Строку(Сертификат);
        Если СертификатКриптографииBase64 = Неопределено Тогда
            Возврат Неопределено;
        КонецЕсли;
    
        Попытка
            АтрибутSignatureValue = ВнешняяКомпонента.CMSSign(Данные, ///Подписываемые данные
                                                            СертификатКриптографииBase64, ///Сертификат в Base64
                                                            "", ///Параоль сертификата (если требуется)
                                                            0, //тип подписи "CAdES-BES"
                                                            Откреп, //открепленная
                                                            17); //РежимВключенияСертификатовКриптографии.ВключатьПолнуюЦепочку
        Исключение
            ВызватьИсключение НСтр("ru = 'Ошибка вызова метода CMSSign компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
        КонецПопытки;
    
        Подпись = Base64Строка(АтрибутSignatureValue);
        Подпись = СтрЗаменить(Подпись, Символы.ПС, "");
        Подпись = СтрЗаменить(Подпись, Символы.ВК, "");
        Возврат Подпись; ///Подписанные данные
    КонецФункции
    

    Обратите внимание на параметр Откреп, который определяет, является ли подпись открепленной. Для SOAP-сообщений подпись чаще всего является присоединенной или охватывающей (enveloped/enveloping), но не открепленной. Параметр 17 (РежимВключенияСертификатовКриптографии.ВключатьПолнуюЦепочку) обеспечивает включение всей цепочки сертификатов, что часто требуется для проверки подписи.

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

Решение 2: Использование COM-объектов CAdESCOM (КриптоПро CSP)

Для криптографических операций в среде Windows широко используется библиотека COM-объектов CAdESCOM от КриптоПро. Этот подход позволяет более гибко работать с различными видами подписей и XML-документов. Для интеграции с ГИИС ДМДК особенно полезен объект CAdESCOM.SignedXML.

  1. Подписание CAdES-BES с помощью CAdESCOM.CadesSignedData:

    Этот метод позволяет создавать подписи типа CAdES-BES, что может быть применимо в некоторых сценариях. Начнем с инициализации необходимых COM-объектов.

    
    // Функция для подписания документа с помощью CAdESCOM
    Функция ПодписатьСертификатомДокумент(ВыбранныйСертификат, СтрокаДляПодписи, Открепл) Экспорт
        Попытка
            comStore = Новый COMОбъект("CAdESCOM.Store");
            comCPSigner = Новый COMОбъект("CAdESCOM.CPSigner"); // Аналог "CAPICOM.Signer".
            comSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
        Исключение
            Сообщить("Не установлен КриптоПро!");
            Возврат Неопределено;
        КонецПопытки;
    
        СтрокаВBase64 = Истина; // Флаг, указывающий, что входные данные в Base64
    
        // Открытие хранилища сертификатов
        comStore.Open(2, // StoreLocation - CAPICOM_CURRENT_USER_STORE.
                     "MY", // StoreName
                     0); // OpenMode - CAPICOM_STORE_OPEN_READ_ONLY.
        comCertificates = comStore.Certificates;
        comStore.Close;
        comStore = Неопределено;
    
        // Установка сертификата для подписи
        comCPSigner.Certificate = ВыбранныйСертификат;
    
        // Очень важно! Указываем кодировку контента, если данные в Base64
        Если СтрокаВBase64 Тогда
            comSignedData.ContentEncoding = 1; // CADESCOM_BASE64_TO_BINARY
        КонецЕсли;
    
        comSignedData.Content = СтрокаДляПодписи; // Подписываемые данные
    
        // Вызов метода SignCades для создания подписи
        ПодписанныеДанные = comSignedData.SignCades(comCPSigner, // Signer
                                                  1, // CadesType, CADESCOM_CADES_BES.
                                                  Открепл // bDetached - "флаг открепленной подписи (исходное сообщение не включается в итоговый CMS-контейнер)".
                                                 ); // EncodingType - по умолчанию CAPICOM_ENCODE_BASE64.
    
        comCPSigner = Неопределено;
        comSignedData = Неопределено;
    
        Возврат УбратьСимволы1013(ПодписанныеДанные); // Функция для очистки символов перевода строки
    КонецФункции
    

    Функция УбратьСимволы1013, вероятно, предназначена для удаления символов возврата каретки (CR) и перевода строки (LF), которые могут быть добавлены при кодировании в Base64 и мешать встраиванию подписи в XML.

  2. Использование CAdESCOM.SignedXML для XMLDSig:

    Для более специфичного подписания XML-документов в формате XMLDSig, который требуется ГИИС ДМДК, рекомендуется использовать объект CAdESCOM.SignedXML. Этот объект предоставляет расширенный функционал для работы с XML-структурами и настройками подписи.

    При его использовании в 1С необходимо выполнить следующие шаги:

    1. Создайте объект: comSignedXML = Новый COMОбъект("CAdESCOM.SignedXML");
    2. Установите содержимое XML-данных для подписи через свойство Content: comSignedXML.Content = XMLСтрока;
    3. Укажите тип подписи. Для SOAP-сообщений, где подпись находится внутри XML-документа, часто используется CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: comSignedXML.SignatureType = 1; (где 1 соответствует CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED).
    4. Создайте объект CAdESCOM.CPSigner, как показано в предыдущем примере, и установите в него сертификат.
    5. Вызовите метод Sign с объектом Signer: ПодписанныеДанные = comSignedXML.Sign(comCPSigner);

    Этот подход обеспечивает более точный контроль над процессом формирования XMLDSig подписи, включая возможность указания ссылок на подписываемые части документа (например, тело SOAP-сообщения с атрибутом Id).

Решение 3: Использование новых возможностей БСП 3.15

В Библиотеке стандартных подсистем (БСП) версии 3.15 появились значительные улучшения для работы с электронными подписями XMLDSig, что делает интеграцию с государственными сервисами, такими как ГИИС ДМДК, более удобной и поддерживаемой штатными средствами 1С.

Ключевые нововведения:

  1. Автоматическое определение параметров XMLDSig:

    Для повышения скорости проверки и создания электронных подписей XMLDSig с помощью процедур Подписать и ПроверитьПодпись общих модулей ЭлектроннаяПодписьКлиент и ЭлектроннаяПодпись предусмотрено автоматическое определение параметров XMLDSig из передаваемого конверта XML. Для этого необходимо оставить незаполненными свойства XPathSignedInfo и XPathПодписываемыйТег структуры, возвращаемой функцией ПараметрыXMLDSig.

  2. Функция КонвертXML для упрощения создания подписей:

    Для упрощения создания электронных подписей XMLDSig в типовых сценариях добавлена функция КонвертXML в общие модули ЭлектроннаяПодписьКлиент и ЭлектроннаяПодпись. В описании этой функции детально изложен состав возможностей, предусмотренных для XML-документа, которые следует учитывать при использовании различных форматов XML.

  3. Поддержка различных алгоритмов канонизации, включая СМЭВ:

    Теперь можно создавать и проверять подписи XMLDSig не только с алгоритмом канонизации Exclusive XML Canonicalization 1.0, но и с алгоритмами Canonical XML 1.0 и Canonical XML 1.1 (для всех трех алгоритмов поддерживается вариант WithComments). Самое важное для ГИИС ДМДК: предусмотрен алгоритм канонизации Единой системы межведомственного электронного взаимодействия (СМЭВ) urn://smev-gov-ru/xmldsig/transform. Это значительно упрощает взаимодействие с государственными сервисами, так как снимает необходимость ручной реализации специфических трансформаций.

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

Особенности работы с ГИИС ДМДК и общие рекомендации

Для успешной интеграции с ГИИС ДМДК необходимо учитывать ряд специфических требований и рекомендаций:

  1. Типы электронных подписей:

    ГИИС ДМДК поддерживает несколько типов электронных подписей:

    • Обезличенная техническая подпись: Используется для автоматизированного взаимодействия систем и может быть получена в ФНС и Центробанке.
    • Личная подпись руководителя: Применяется для работы в личном кабинете и через сервис интеграции.
    • Подпись физического лица с машиночитаемой доверенностью (МЧД): Используется для сотрудников, действующих от имени организации.
  2. Требования к сертификатам:

    Несмотря на то, что ранее ГИИС ДМДК могла требовать сертификаты с длительным сроком действия (например, 11 лет), фактическое подписание производится закрытым ключом, срок действия которого обычно ограничен 1 годом (максимум 15 месяцев для КриптоПро CSP). Из-за этого сертификаты часто требуют ежегодного перевыпуска.

  3. Этапы интеграции:

    Взаимодействие с ГИИС ДМДК обычно происходит в два этапа:

    1. Сначала отправка команды, которая возвращает идентификатор запроса.
    2. Затем проверка статуса запроса по этому идентификатору для получения результата его обработки.
  4. Тестовый контур:

    Настоятельно рекомендуется начинать настройку и отладку интеграции на тестовом сервере ГИИС ДМДК. Логика взаимодействия и ограничения системы могут быть сложными, и тестовый контур позволяет избежать ошибок в рабочей среде.

  5. Защищенный канал связи:

    Для обмена данными с ГИИС ДМДК необходимо организовать защищенный канал передачи данных через TLS. Это подразумевает установку криптопровайдера (например, КриптоПро CSP) и ПО, такого как Stunnel, на рабочем месте, с которого осуществляется подключение. Stunnel позволяет создавать защищенные туннели для обычных TCP-соединений.

  6. Возможные проблемы и их решения:

    Часто возникают ошибки, связанные с некорректной канонизацией частей SOAP-сообщения (тела или блока SignedInfo). Возможно, потребуется "ручная" канонизация шаблона перед подписанием. Также важно убедиться, что входные данные для функций подписания являются валидным XML. Следует внимательно проверять OID алгоритмов подписи и хеширования на соответствие требованиям компоненты, а в некоторых случаях может потребоваться изменение порядка байтов хеша или значения подписи перед кодированием в Base64.

    В некоторых случаях для решения проблемы подписания, помимо рассмотренных компонент, может использоваться компонента xades из "Бухгалтерии государственного учреждения 2" (БГУ2), которая также предназначена для работы с XML-подписями.

Таким образом, интеграция с ГИИС ДМДК и подписание SOAP-сообщений электронной подписью в 1С — это многогранная задача, требующая внимательного подхода к выбору инструментов и соблюдению специфических требований. Используя комбинацию представленных решений и рекомендаций, вы сможете успешно реализовать необходимый функционал.

← На главную