При интеграции систем на платформе 1С с государственными информационными системами, такими как ГИС ЖКХ или ГИС ГМП, разработчики сталкиваются с жестким требованием к безопасности: все отправляемые XML-запросы должны быть подписаны электронной цифровой подписью (ЭЦП) по стандарту XAdES-BES (XML Advanced Electronic Signatures - Basic Electronic Signature) с использованием алгоритмов ГОСТ.
Поскольку встроенные механизмы платформы 1С долгое время не поддерживали высокоуровневое формирование подписей этого стандарта "из коробки", в сообществе разработчиков стала популярной внешняя компонента Xades1C.Xades1C. В этой статье мы подробно разберем, откуда берется эта библиотека, как решить проблемы с ее регистрацией в операционной системе Windows, почему может возникать ошибка отсутствия метода SignSTR, а также рассмотрим альтернативные способы реализации подписи.
Выясним причину появления этой библиотеки. Компонента Xades1C.Xades1C не является официальным продуктом фирмы «1С» или компании «КриптоПро». На самом деле это неофициальная обертка (wrapper), написанная сторонними разработчиками на языке C# (платформа .NET).
В основу решения лег официальный демонстрационный пример подписания XML-документов, который разработчики ГИС ЖКХ публиковали на своем портале в разделах технической документации. Данный пример базировался на доработанной библиотеке Microsoft.Xades (первоначально созданной французским подразделением Microsoft) для работы с криптопровайдером КриптоПро CSP. Сторонние разработчики оформили этот код в виде динамической библиотеки (DLL) и экспортировали ее функции наружу через COM-интерфейс, чтобы к ним можно было легко обращаться из кода 1С.
Проанализируем ситуацию, когда разработчик находит библиотеку xades.dll или cades.dll, но при попытке вызвать метод SignSTR получает ошибку о том, что метод не найден. Этому есть две основные причины:
Xades1C.dll с официальными библиотеками от КриптоПро (например, cades.dll / CADESCOM). Официальный SDK от КриптоПро предоставляет низкоуровневый доступ к объектам подписи. Он работает с объектной моделью документа (DOM) и стандартно не содержит простого метода типа SignSTR, который бы принимал строку XML на вход и сразу возвращал подписанную строку.Xades1C. В ранних версиях подписание было реализовано исключительно через работу с физическими файлами на диске (методы вроде SignFile). Метод SignSTR (работа непосредственно со строковыми переменными XML в памяти) появился в более поздних модификациях библиотеки для оптимизации быстродействия и избавления от лишних дисковых операций ввода-вывода. Если этого метода нет, вам необходимо использовать файловые методы компоненты либо найти обновленную версию сборки.Рассмотрим подробнее процесс регистрации библиотеки в операционной системе. Очень часто разработчики совершают стандартную ошибку, пытаясь зарегистрировать файл Xades1C.dll с помощью утилиты командной строки regsvr32. При этом система выдает ошибку об отсутствии точки входа DllRegisterServer.
Эта ошибка закономерна. Утилита regsvr32 предназначена исключительно для классических COM-библиотек (написанных, например, на C++ или Delphi). Так как Xades1C.dll представляет собой .NET-сборку, ее регистрация в качестве COM-сервера выполняется с помощью специализированного инструмента из состава .NET Framework — RegAsm.exe (Assembly Registration Tool).
Выполним регистрацию компоненты по шагам:
Framework, а для 64-битного — из папки Framework64./tlb (для создания библиотеки типов) и /codebase (для записи пути к файлу в системный реестр):Для 32-битного окружения:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe "C:\PathToBin\Xades1C.dll" /tlb /codebase
Для 64-битного окружения:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe "C:\PathToBin\Xades1C.dll" /tlb /codebase
Важное примечание: Для успешной работы компоненты на целевом компьютере обязательно должен быть установлен криптопровайдер КриптоПро CSP, программный модуль КриптоПро .NET, а также сам пакет .NET Framework версии 4.0 или выше.
Посмотрим, как правильно организовать хранение и вызов компоненты внутри информационной базы 1С, чтобы избежать ручного копирования файлов на каждом рабочем месте пользователя.
Наиболее надежный способ — загрузить файл Xades1C.dll в Общие макеты вашей конфигурации с типом "Двоичные данные". Назовем макет, например, Компонента_Xades1C.
Разберем по шагам программный алгоритм инициализации компоненты из макета 1С:
Функция ПолучитьОбъектXades() Экспорт
ИмяФайлаБиблиотеки = ПолучитьИмяВременногоФайла("dll");
// Извлекаем двоичные данные из макета конфигурации
МакетБиблиотеки = ПолучитьОбщийМакет("Компонента_Xades1C");
МакетБиблиотеки.Записать(ИмяФайлаБиблиотеки);
// Пытаемся инициализировать объект
Попытка
XadesОбъект = Новый COMОбъект("Xades1C.Xades1C");
Исключение
// Если объект не зарегистрирован, пробуем произвести регистрацию программно
// Для этого конструируем команду для RegAsm
ПутьКRegAsm = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe";
СтрокаЗапуска = """" + ПутьКRegAsm + """ """ + ИмяФайлаБиблиотеки + """ /tlb /codebase /silent";
ЗапуститьПриложение(СтрокаЗапуска, , Истина);
// Повторная попытка создания объекта после регистрации
Попытка
XadesОбъект = Новый COMОбъект("Xades1C.Xades1C");
Исключение
ВызватьИсключение "Не удалось подключить компоненту Xades1C. " + ОписаниеОшибки();
КонецПопытки;
КонецПопытки;
Возврат XadesОбъект;
КонецФункции
Если используется корректная версия сборки библиотеки Xades1C, содержащая строковые методы подписи, вызов функции шифрования и подписания XML-документа на встроенном языке 1С будет выглядеть следующим образом:
// Получаем инициализированный COM-объект
Xades = ПолучитьОбъектXades();
// Подготовка параметров для вызова метода SignSTR
ЗапросXML = "<?xml version=""1.0"" encoding=""UTF-8""?><Document>...</Document>";
IdПодписи = "Sign_" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
ОтпечатокСертификата = "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"; // SHA-1 отпечаток без пробелов
ПарольКонтейнера = "MySecretPassword123"; // Оставьте пустым "", если пароль на контейнер отсутствует
Попытка
// Вызов метода подписания
ПодписанныйЗапросXML = Xades.SignSTR(ЗапросXML, IdПодписи, ОтпечатокСертификата, ПарольКонтейнера);
Сообщить("Документ успешно подписан!");
Исключение
Сообщить("Ошибка при подписании документа: " + ОписаниеОшибки());
КонецПопытки;
Разберем параметры метода подробнее:
ЗапросXML (Строка) — исходный текст XML-документа, сформированный в 1С, который необходимо отправить в ГИС.IdПодписи (Строка) — уникальный строковый идентификатор тега подписи в XML. Он связывает тело документа с элементом Signature. Обычно генерируется динамически с помощью встроенной функции Новый УникальныйИдентификатор.ОтпечатокСертификата (Строка) — хэш (SHA-1) установленного в системе личного сертификата электронной подписи. Его можно посмотреть в свойствах сертификата через консоль сертификатов Windows или КриптоПро CSP. Все пробелы в строке отпечатка должны быть удалены, а регистр букв не имеет значения.ПарольКонтейнера (Строка) — пароль доступа к закрытому ключу вашего сертификата. Если закрытый ключ хранится в реестре Windows без пароля или на токене с запомненным PIN-кодом, передается пустая строка.Что делать, если использование технологии COM накладывает слишком много ограничений (например, сервер 1С работает под управлением операционной системы Linux или возникают неразрешимые проблемы с правами доступа учетной записи USR1CV8 в реестре Windows)? Рассмотрим три альтернативных подхода:
Вместо создания COM-объекта логику подписания можно упаковать в небольшое независимое консольное приложение на C# (.exe файл), которое будет принимать на вход параметры через командную строку (или через временные файлы на диске), подписывать XML с помощью КриптоПро .NET и выдавать результат обратно. Из кода 1С такое приложение вызывается с помощью штатной команды ЗапуститьПриложение. Плюс этого метода — полное отсутствие необходимости регистрировать какие-либо COM-классы в реестре Windows.
Создается компактный локальный веб-сервис на технологии .NET Core (ASP.NET Core), который запускается в операционной системе как служба Windows или демон Linux. 1С общается с этим веб-сервисом посредством HTTP-запросов (HTTPСоединение). Платформа 1С отправляет POST-запрос с сырым XML, веб-сервис подписывает его локально установленным КриптоПро и возвращает готовый подписанный XML в теле ответа. Это наиболее современное, масштабируемое и кроссплатформенное решение.
Некоторые конфигурации используют прямое обращение к низкоуровневым функциям Windows CryptoAPI или библиотеке CADESCOM. При этом структура XMLDSIG / XAdES-BES собирается вручную кодом 1С посредством работы со строками или через объект ЗаписьXML. Это самый сложный в реализации путь, требующий от разработчика глубоких познаний в криптографических стандартах XML-подписей, однако он избавляет от необходимости поддержки сторонних кастомных библиотек.