При необходимости интеграции системы 1С с государственным информационным интегрированным сервисом ДМДК (ГИИС ДМДК) одной из ключевых и часто сложных задач является корректное подписание SOAP-сообщений электронной подписью. Это требует специфических знаний как в области работы с веб-сервисами, так и в применении криптографических средств в среде 1С. В данной статье мы подробно рассмотрим различные подходы и примеры кода, которые помогут вам успешно реализовать эту интеграцию.
Общие принципы подписания SOAP-сообщений с использованием XMLDSig
Интеграция с ГИИС ДМДК предполагает использование формата XML Digital Signature (XMLDSig) для подписи XML-документов, в том числе SOAP-сообщений. Электронная подпись, как правило, размещается в секции Header SOAP-сообщения. Критически важно подписывать определенные части сообщения, чаще всего именно Body, а не весь SOAP-конверт целиком. Тело сообщения должно содержать атрибут Id, чтобы на него можно было сослаться в подписи. Процесс создания подписи включает в себя следующие шаги:
Body необходимыми данными и добавление атрибута Id.Security, которая будет содержать подпись.Security в Header SOAP-сообщения.Для корректного взаимодействия с государственными сервисами, такими как ГИИС ДМДК, часто требуется использовать специфический алгоритм канонизации СМЭВ: urn://smev-gov-ru/xmldsig/transform. Этот алгоритм трансформации обеспечивает единообразное представление XML-документа перед подписанием, что жизненно важно для успешной проверки подписи. Выбор алгоритмов хеширования и подписи (например, ГОСТ Р 34.10-2012 и ГОСТ Р 34.11-2012) также должен соответствовать требованиям ГИИС ДМДК.
В платформе 1С для работы с криптографией и электронными подписями широко используются внешние компоненты. Компонента "КомпонентаXMLDSig", упомянутая в обсуждении, является частью Библиотеки стандартных подсистем (БСП) и активно применяется в типовых конфигурациях, таких как "Управление торговлей" (УТ) версии 11. Рассмотрим шаги и примеры кода для ее использования.
Для начала необходимо получить двоичные данные компоненты из общих макетов и подключить ее. В типовых конфигурациях эти данные часто хранятся в общем макете "КомпонентаXMLDSig".
// Функция для получения и подключения компоненты
&НаКлиенте
Функция КомпонентаПодписи()
КомпонентаДвоичныеДанные = ПолучитьКомпонентуПодписи;
АдресМакета = ПоместитьВоВременноеХранилище(КомпонентаДвоичныеДанные);
Если ПодключитьВнешнююКомпоненту(АдресМакета, "XMLDSignAddInSymbolicName", ТипВнешнейКомпоненты.Native) Тогда
ВнешняяКомпонента = Новый("AddIn.XMLDSignAddInSymbolicName.XMLDSignAddIn");
Иначе
УстановитьВнешнююКомпоненту(АдресМакета);
Если ПодключитьВнешнююКомпоненту(АдресМакета, "XMLDSignAddInSymbolicName", ТипВнешнейКомпоненты.Native) Тогда
ВнешняяКомпонента = Новый("AddIn.XMLDSignAddInSymbolicName.XMLDSignAddIn");
Иначе
Сообщить(ОписаниеОшибки);
ВнешняяКомпонента = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ВнешняяКомпонента;
КонецФункции
// Серверная функция для получения двоичных данных компоненты
&НаСервере
Функция ПолучитьКомпонентуПодписи() Экспорт
Возврат ПолучитьОбщийМакет("КомпонентаXMLDSig");
КонецФункции
Перед подписанием необходимо получить данные сертификата в формате Base64. Обычно сертификаты хранятся в справочниках 1С (например, "Сертификаты ЭЦП") в виде двоичных данных.
// Серверная функция для получения сертификата в Base64 строке
&НаСервере
Функция ПолучитьСертификатBase64Строку(Ссылка) Экспорт
ДанныеСертификата = Ссылка.ФайлСертификата.Получить(); ///Двоичные данные сертификата (Из справочника Сертификаты ЭЦП)
СтрокаBase64 = Base64Строка(ДанныеСертификата);
Значение = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
Значение = СтрЗаменить(Значение, Символы.ПС, "");
Возврат Значение;
КонецФункции
Теперь, когда компонента подключена и сертификат подготовлен, мы можем использовать метод CMSSign компоненты для подписания данных. Важно правильно передать подписываемые данные, сертификат и указать тип подписи.
// Функция для подписания данных с помощью КомпонентыXMLDSig
&НаКлиенте
Функция ПодписатьДанные(Сертификат, Данные, Откреп = Ложь)
ВнешняяКомпонента = КомпонентаПодписи;
Если ВнешняяКомпонента = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
СертификатКриптографииBase64 = ПолучитьСертификатBase64Строку(Сертификат);
Если СертификатКриптографииBase64 = Неопределено Тогда
Возврат Неопределено;
КонецЕсли;
Попытка
АтрибутSignatureValue = ВнешняяКомпонента.CMSSign(Данные, ///Подписываемые данные
СертификатКриптографииBase64, ///Сертификат в Base64
"", ///Параоль сертификата (если требуется)
0, //тип подписи "CAdES-BES"
Откреп, //открепленная
17); //РежимВключенияСертификатовКриптографии.ВключатьПолнуюЦепочку
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода CMSSign компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецПопытки;
Подпись = Base64Строка(АтрибутSignatureValue);
Подпись = СтрЗаменить(Подпись, Символы.ПС, "");
Подпись = СтрЗаменить(Подпись, Символы.ВК, "");
Возврат Подпись; ///Подписанные данные
КонецФункции
Обратите внимание на параметр Откреп, который определяет, является ли подпись открепленной. Для SOAP-сообщений подпись чаще всего является присоединенной или охватывающей (enveloped/enveloping), но не открепленной. Параметр 17 (РежимВключенияСертификатовКриптографии.ВключатьПолнуюЦепочку) обеспечивает включение всей цепочки сертификатов, что часто требуется для проверки подписи.
Также стоит отметить, что данная компонента 1С является разработкой самой фирмы 1С и используется в типовых конфигурациях, что гарантирует ее актуальность и поддержку.
Для криптографических операций в среде Windows широко используется библиотека COM-объектов CAdESCOM от КриптоПро. Этот подход позволяет более гибко работать с различными видами подписей и XML-документов. Для интеграции с ГИИС ДМДК особенно полезен объект CAdESCOM.SignedXML.
Этот метод позволяет создавать подписи типа 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.
Для более специфичного подписания XML-документов в формате XMLDSig, который требуется ГИИС ДМДК, рекомендуется использовать объект CAdESCOM.SignedXML. Этот объект предоставляет расширенный функционал для работы с XML-структурами и настройками подписи.
При его использовании в 1С необходимо выполнить следующие шаги:
comSignedXML = Новый COMОбъект("CAdESCOM.SignedXML");Content: comSignedXML.Content = XMLСтрока;CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED: comSignedXML.SignatureType = 1; (где 1 соответствует CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED).CAdESCOM.CPSigner, как показано в предыдущем примере, и установите в него сертификат.Sign с объектом Signer: ПодписанныеДанные = comSignedXML.Sign(comCPSigner);Этот подход обеспечивает более точный контроль над процессом формирования XMLDSig подписи, включая возможность указания ссылок на подписываемые части документа (например, тело SOAP-сообщения с атрибутом Id).
В Библиотеке стандартных подсистем (БСП) версии 3.15 появились значительные улучшения для работы с электронными подписями XMLDSig, что делает интеграцию с государственными сервисами, такими как ГИИС ДМДК, более удобной и поддерживаемой штатными средствами 1С.
Ключевые нововведения:
Для повышения скорости проверки и создания электронных подписей XMLDSig с помощью процедур Подписать и ПроверитьПодпись общих модулей ЭлектроннаяПодписьКлиент и ЭлектроннаяПодпись предусмотрено автоматическое определение параметров XMLDSig из передаваемого конверта XML. Для этого необходимо оставить незаполненными свойства XPathSignedInfo и XPathПодписываемыйТег структуры, возвращаемой функцией ПараметрыXMLDSig.
КонвертXML для упрощения создания подписей:
Для упрощения создания электронных подписей XMLDSig в типовых сценариях добавлена функция КонвертXML в общие модули ЭлектроннаяПодписьКлиент и ЭлектроннаяПодпись. В описании этой функции детально изложен состав возможностей, предусмотренных для XML-документа, которые следует учитывать при использовании различных форматов XML.
Теперь можно создавать и проверять подписи XMLDSig не только с алгоритмом канонизации Exclusive XML Canonicalization 1.0, но и с алгоритмами Canonical XML 1.0 и Canonical XML 1.1 (для всех трех алгоритмов поддерживается вариант WithComments). Самое важное для ГИИС ДМДК: предусмотрен алгоритм канонизации Единой системы межведомственного электронного взаимодействия (СМЭВ) urn://smev-gov-ru/xmldsig/transform. Это значительно упрощает взаимодействие с государственными сервисами, так как снимает необходимость ручной реализации специфических трансформаций.
Использование этих новых возможностей БСП является наиболее предпочтительным подходом, поскольку это штатное решение от 1С, которое учитывает специфику взаимодействия с государственными системами.
Для успешной интеграции с ГИИС ДМДК необходимо учитывать ряд специфических требований и рекомендаций:
ГИИС ДМДК поддерживает несколько типов электронных подписей:
Несмотря на то, что ранее ГИИС ДМДК могла требовать сертификаты с длительным сроком действия (например, 11 лет), фактическое подписание производится закрытым ключом, срок действия которого обычно ограничен 1 годом (максимум 15 месяцев для КриптоПро CSP). Из-за этого сертификаты часто требуют ежегодного перевыпуска.
Взаимодействие с ГИИС ДМДК обычно происходит в два этапа:
Настоятельно рекомендуется начинать настройку и отладку интеграции на тестовом сервере ГИИС ДМДК. Логика взаимодействия и ограничения системы могут быть сложными, и тестовый контур позволяет избежать ошибок в рабочей среде.
Для обмена данными с ГИИС ДМДК необходимо организовать защищенный канал передачи данных через TLS. Это подразумевает установку криптопровайдера (например, КриптоПро CSP) и ПО, такого как Stunnel, на рабочем месте, с которого осуществляется подключение. Stunnel позволяет создавать защищенные туннели для обычных TCP-соединений.
Часто возникают ошибки, связанные с некорректной канонизацией частей SOAP-сообщения (тела или блока SignedInfo). Возможно, потребуется "ручная" канонизация шаблона перед подписанием. Также важно убедиться, что входные данные для функций подписания являются валидным XML. Следует внимательно проверять OID алгоритмов подписи и хеширования на соответствие требованиям компоненты, а в некоторых случаях может потребоваться изменение порядка байтов хеша или значения подписи перед кодированием в Base64.
В некоторых случаях для решения проблемы подписания, помимо рассмотренных компонент, может использоваться компонента xades из "Бухгалтерии государственного учреждения 2" (БГУ2), которая также предназначена для работы с XML-подписями.
Таким образом, интеграция с ГИИС ДМДК и подписание SOAP-сообщений электронной подписью в 1С — это многогранная задача, требующая внимательного подхода к выбору инструментов и соблюдению специфических требований. Используя комбинацию представленных решений и рекомендаций, вы сможете успешно реализовать необходимый функционал.