Как присоединить электронную подпись к XML-файлу в 1С

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

При работе с электронным документооборотом программисты 1С часто сталкиваются с задачей подписания XML-файлов. Одной из самых запутанных тем является выбор способа «присоединения» подписи. Часто возникает путаница: нужно ли вставлять подпись внутрь структуры XML (стандарт XMLDSig) или создать единый бинарный файл, содержащий и подпись, и исходные данные (присоединенная подпись PKCS#7). Для регулярной передачи таких файлов программа для обмена данными по расписанию настраивается поверх существующего плана обмена без изменения самих конфигураций.

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

Понятие присоединенной и отсоединенной подписи

Прежде чем переходить к коду, давайте разберем теорию. Существует два основных способа формирования подписи в формате CMS/PKCS#7:

  1. Отсоединенная подпись (Detached): Создается отдельный файл (обычно с расширением .p7s или .sig), который содержит только криптографический отпечаток. Оригинальный XML-файл при этом остается неизменным. Для проверки такой подписи нужны оба файла.
  2. Присоединенная подпись (Attached): Создается новый файл-контейнер. Внутри него упакованы и ваши исходные данные (XML-текст), и сама подпись. Если открыть такой файл в текстовом редакторе, вы увидите бинарный заголовок («кракозябры»), за которыми следует ваш текст.

Многие внешние системы (например, государственные порталы или КриптоАРМ) под «присоединением подписи» понимают именно второй вариант — создание единого бинарного контейнера. В случаях, когда прямая интеграция с ними затруднена, платформа для создания программных роботов выполняет действия в интерфейсе внешних программ без API для обмена данными.

Вариант 1: Использование стандартного объекта МенеджерКриптографии

Если вам нужно получить присоединенную подпись в формате PKCS#7 (как это делает КриптоАРМ), проще всего использовать встроенный объект платформы МенеджерКриптографии. Рассмотрим, как это сделать правильно.

Ошибка многих разработчиков заключается в игнорировании четвертого параметра метода Подписать(). Посмотрите на следующий пример кода:


// Инициализируем менеджер криптографии
// Параметры: имя криптопровайдера, путь к модулю (обычно пустые для CryptoPro), тип (80 для ГОСТ 2012)
МенеджерКриптографии = Новый МенеджерКриптографии("", "", 80);

// Устанавливаем пароль к закрытому ключу сертификата
МенеджерКриптографии.ПарольДоступаКЗакрытомуКлючу = "ВашПароль";

// Файлы
ФайлЗапроса = "C:\Temp\запрос.xml";
ФайлРезультата = "C:\Temp\запрос.xml.p7s";

// ВАЖНО: Четвертый параметр 'ТолькоПодпись'
// Ложь — создается присоединенная подпись (данные внутри)
// Истина — создается отсоединенная подпись (только подпись)
МенеджерКриптографии.Подписать(ФайлЗапроса, ФайлРезультата, Сертификат, Ложь);

Если вы установите четвертый параметр в значение Ложь, платформа упакует ваш XML внутрь .p7s. Это и будет тот самый «файл с подписью в начале», который часто требуют информационные системы. Проанализируем результат: теперь ФайлРезультата — это самодостаточный объект, который можно отправить получателю без исходного XML. Для быстрой реализации такого механизма можно воспользоваться обработкой для подписания файлов средствами платформы 1С.

Вариант 2: Использование Библиотеки стандартных подсистем (БСП)

Если в вашей конфигурации внедрена БСП (модуль ЭлектроннаяПодпись), рекомендуется использовать её функции. Это обеспечит корректную работу с хранилищами сертификатов и логирование операций.

Для серверного (синхронного) подписания данных, чтобы получить присоединенную подпись, используем следующий алгоритм:


// Подготовка данных
ДанныеДляПодписи = Новый ДвоичныеДанные("C:\Temp\запрос.xml");

// Параметры подписания
ПараметрыПодписи = ЭлектроннаяПодпись.ПараметрыПодписи();
ПараметрыПодписи.Сертификат = ВыбранныйСертификат;

// Метод Подписать на сервере возвращает ДвоичныеДанные готового контейнера
// По умолчанию БСП формирует отсоединенную подпись. 
// Чтобы включить данные в подпись, нужно настроить параметры расширения или использовать низкоуровневые методы.
РезультатПодписания = ЭлектроннаяПодпись.Подписать(ДанныеДляПодписи, ПараметрыПодписи);

// Запись результата в файл
РезультатПодписания.Записать("C:\Temp\запрос_с_подписью.sig");

Обратите внимание, что в современных версиях БСП клиентские методы (ЭлектроннаяПодписьКлиент.Подписать) являются асинхронными. Они возвращают результат через ОписаниеОповещения. Если вам нужно встроить подписание в существующий линейный код, всегда выполняйте подписание на стороне сервера.

Вариант 3: Стандарт XMLDSig (Встроенная подпись)

Иногда под «присоединением подписи к XML» понимают стандарт XMLDSig (Enveloped). В этом случае подпись в формате XML вставляется непосредственно в структуру самого документа в виде тега <Signature>. Это принципиально отличается от бинарного контейнера PKCS#7.

Для реализации XMLDSig через БСП часто используют следующий подход (разберем пример, который часто вызывает ошибки):


ПараметрыКонверта = ЭлектроннаяПодписьКлиент.ПараметрыКонвертаXML();
ПараметрыКонверта.СообщениеXML = ТекстВашегоXML; // Передаем содержимое файла

ОписаниеДанных = Новый Структура;
ОписаниеДанных.Вставить("Операция", "ПодписаниеДанных");
ОписаниеДанных.Вставить("Данные", ЭлектроннаяПодписьКлиент.КонвертXML(ПараметрыКонверта));

// Вызов асинхронного метода
ЭлектроннаяПодписьКлиент.Подписать(ОписаниеДанных, Неопределено, ОбработкаРезультата);

Важное предостережение: Если при использовании этого метода вы получаете ошибку Поле объекта не обнаружено (КонвертSOAP), это означает, что программный интерфейс БСП ожидает структуру для работы с веб-сервисами (SOAP), а вы передали обычные данные. Проверьте, заполнены ли свойства структуры ПараметрыКонвертаXML и соответствует ли ваш XML требованиям схемы DSIG.

Анализ типичных проблем и рекомендации

Рассмотрим основные причины, по которым подпись может «не подходить» принимающей стороне:

  1. Кодировка: XML часто сохраняется в UTF-8. При создании присоединенной подписи через бинарные данные убедитесь, что вы не изменили кодировку документа, иначе подпись станет невалидной сразу после создания. Используйте ЗаписьТекста с явным указанием кодировки без BOM.
  2. Версия алгоритма ГОСТ: Для современных сертификатов (выданных после 2018-2019 гг.) необходимо использовать алгоритм ГОСТ Р 34.10-2012. В 1С это соответствует типу криптопровайдера 80.
  3. Синхронность кода: Если вы пишете обработку, которая должна выполняться в цикле или регламентном задании, забудьте про клиентские методы БСП (с приставкой Клиент). Используйте только серверные методы МенеджерКриптографии или ЭлектроннаяПодпись, так как они работают в синхронном режиме и не требуют взаимодействия с пользователем.

Подводя итог, выясним: если вам нужно просто «склеить» файл и подпись в один файл (как в КриптоАРМ), используйте МенеджерКриптографии.Подписать(..., Ложь). Если же ваша задача — интеграция с государственными ИС через API, скорее всего, вам потребуется стандарт XMLDSig, который лучше реализовывать через специализированные методы БСП или внешние компоненты (например, КриптоПро ЭЦП Browser plug-in).

← На главную