При работе с электронным документооборотом в 1С часто возникает задача подписания файлов электронной подписью. Одной из специфических и порой сложных требований является создание присоединенной электронной подписи, когда сама подпись находится непосредственно внутри подписанного файла, а не в отдельном файле (отсоединенная подпись). В этой статье мы подробно рассмотрим, как решить эту задачу в контексте 1С, анализируя ограничения встроенных средств и предлагая альтернативные решения.
Основная проблема, с которой мы сталкиваемся, заключается в том, что стандартные механизмы 1С для подписания файлов, особенно текстовых (TXT), преимущественно ориентированы на создание отсоединенной подписи. Отсоединенная подпись представляет собой отдельный файл, который содержит только саму подпись и ссылку на исходные данные, которые она подтверждает. Принимающая же сторона в некоторых случаях требует, чтобы и данные, и подпись были в одном файле, что чаще всего подразумевает формат PKCS#7 (CMS).
Начнем с анализа встроенных возможностей 1С. Если мы попытаемся использовать стандартный объект МенеджерКриптографии для подписания файла, то увидим, что он по умолчанию создает отсоединенную подпись.
Рассмотрим пример кода, демонстрирующий такое поведение:
ТипМенеджераКриптографии = 81;
МенеджерКриптографии = Новый МенеджерКриптографии("", "", ТипМенеджераКриптографии);
// ...
МенеджерКриптографии.ВключениеСертификатовВПодпись = РежимВключенияСертификатовКриптографии.НеВключать;
МенеджерКриптографии.Подписать(ФайлЗапроса, ФайлЗапроса + ".p7s", Сертификат);
В этом примере МенеджерКриптографии.Подписать(ФайлЗапроса, ФайлЗапроса + ".p7s", Сертификат) создаст файл подписи с расширением .p7s (или аналогичным), который будет находиться отдельно от исходного ФайлЗапроса. Это и есть отсоединенная подпись.
Почему же 1С так поступает? Причина кроется в особенностях формата TXT. Обычный текстовый файл не имеет встроенной структуры для хранения метаданных, таких как цифровая подпись, без изменения его исходного содержимого. Если мы просто добавим подпись в конец текстового файла, это изменит сам текст, и подпись станет недействительной. В отличие от TXT, формат PDF, например, поддерживает присоединенную подпись, потому что цифровая подпись вставляется в отдельный слой документа, не затрагивая его основное содержимое. Это позволяет даже многократно подписывать документ, сохраняя валидность всех подписей.
Как отмечается в документации к Библиотеке стандартных подсистем (БСП) 1С, "В программе 1С:Предприятие возможна работа только с отсоединенной электронной подписью. Работа с присоединенными подписями и подписями внутри документа в программе недоступна." Это подтверждает, что встроенные средства 1С не предназначены для создания присоединенных подписей для большинства форматов документов, за исключением некоторых специфических случаев, таких как PDF.
Один из возможных путей решения проблемы — использование внешних криптографических компонент, доступных через COM-объекты. Платформа 1С позволяет работать с такими объектами, и библиотека CAdESCOM, входящая в состав КриптоПро CSP, является мощным инструментом для работы с цифровыми подписями.
Мы можем попытаться создать присоединенную подпись с помощью CAdESCOM.CadesSignedData. Рассмотрим пример такого кода:
oSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
oSignedData.Content = Base64Строка(ДвоичныеДанные);
oSignedMessage = oSignedData.SignCades(oCertificate, 65535, false, 0);
В этом коде мы создаем объект CAdESCOM.CadesSignedData, передаем ему содержимое файла в кодировке Base64 через свойство Content, а затем пытаемся подписать его методом SignCades, используя сертификат oCertificate и определенные параметры.
Однако при выполнении этого кода мы можем столкнуться с ошибкой: CAdESCOM.CadesSignedData.1 Интерфейс не поддерживается. Это довольно распространенная ошибка, которая может указывать на несколько причин:
CAdESCOM устарела и не содержит необходимого функционала для выбранного типа подписи или режима работы. Некоторые режимы или типы подписей могли быть добавлены в более поздних версиях библиотеки.SignCades (например, 65535, false, 0), могут быть интерпретированы компонентой как запрос неподдерживаемого интерфейса или типа подписи. Важно тщательно свериться с документацией CAdESCOM для корректных значений флагов и типов подписей для присоединенной подписи PKCS#7 (CMS).Если нам удастся корректно использовать CAdESCOM для создания присоединенной подписи, результатом будет один бинарный файл. При просмотре такого файла в обычном текстовом редакторе он будет выглядеть как набор нечитаемых символов ("иероглифов"), поскольку он содержит бинарные данные подписи вместе с исходным текстом. Именно такой формат, скорее всего, ожидает принимающая сторона, если она использует "КриптоАРМ со снятой галочкой 'сохранить подпись в отдельном файле'".
Учитывая ограничения 1С и сложности с CAdESCOM, наиболее надежным и проверенным решением является использование внешних консольных утилит или программ, которые специально предназначены для работы с криптографией.
Утилита csptest.exe является частью комплекта КриптоПро CSP и предоставляет широкие возможности для работы с криптографическими операциями из командной строки. С ее помощью мы можем создать присоединенную подпись в формате PKCS#7 (CMS).
Рассмотрим пример команды для подписания файла, который создает присоединенную подпись:
rem Подписать файл присоединенной ЭЦП
csptest -sfsign -sign -in 08_110400716550_002_19012023_B6662EA1-EC95-423A-95B5-793526329DA9.xml -out 08_110400716550_002_19012023_B6662EA1-EC95-423A-95B5-793526329DA9.xml.sig -my B030C18CB16B8A0EFBDB7DB5F8131D5C2E2617D1 -addsigtime -add
Разберем параметры этой команды:
csptest: Вызов самой утилиты.-sfsign: Указывает на выполнение операции с подписью (Signature File operations).-sign: Обозначает, что мы хотим подписать файл.-in <исходный_файл>: Путь к исходному файлу, который необходимо подписать (в примере это 08_110400716550_002_19012023_B6662EA1-EC95-423A-95B5-793526329DA9.xml, но это может быть любой текстовый файл).-out <выходной_файл_с_подписью>: Путь и имя для выходного файла, который будет содержать присоединенную подпись (в примере это 08_110400716550_002_19012023_B6662EA1-EC95-423A-95B5-793526329DA9.xml.sig). Отсутствие флага -detached или -nostore гарантирует создание присоединенной подписи, то есть данные будут включены в выходной файл.-my <отпечаток_сертификата>: Отпечаток (хеш) сертификата, которым будет осуществляться подписание. Это позволяет программе найти нужный сертификат в хранилище пользователя.-addsigtime: Добавляет в подпись атрибут "время подписи".-add: Добавляет информацию о подписи.Результатом выполнения этой команды будет файл 08_110400716550_002_19012023_B6662EA1-EC95-423A-95B5-793526329DA9.xml.sig, который будет содержать как исходные данные, так и саму подпись в одном бинарном блоке. Этот файл является присоединенной подписью в формате PKCS#7 (CMS) и будет соответствовать требованиям принимающей стороны, ожидающей "КриптоАРМ подписано со снятой галочкой 'сохранить подпись в отдельном файле'".
Для вызова этой утилиты из 1С мы можем использовать объект ЗапуститьПриложение или WShell.Run, передавая ей сформированную командную строку.
&НаКлиенте
Процедура ПодписатьФайлЧерезCsptest()
// Предполагается, что файл уже сохранен на диск
ПутьКИсходномуФайлу = "C:\МоиДокументы\текстовый_файл.txt";
ПутьКПодписанномуФайлу = "C:\МоиДокументы\текстовый_файл.txt.sig";
ОтпечатокСертификата = "B030C18CB16B8A0EFBDB7DB5F8131D5C2E2617D1"; // Замените на реальный отпечаток
КомандаCsptest = "csptest -sfsign -sign -in " + """""" + ПутьКИсходномуФайлу + """""" +
" -out " + """""" + ПутьКПодписанномуФайлу + """""" +
" -my " + ОтпечатокСертификата + " -addsigtime -add";
// Для запуска на клиенте
WShell = Новый COMОбъект("WScript.Shell");
WShell.Run(КомандаCsptest, 0, Истина); // 0 - скрыть окно, Истина - дождаться завершения
Сообщить("Файл успешно подписан и сохранен как: " + ПутьКПодписанномуФайлу);
Исключение
Сообщить("Ошибка при подписании файла: " + ОписаниеОшибки());
КонецПроцедуры
Важно: Утилита csptest.exe должна быть доступна в системном PATH или по полному пути. Также необходимо, чтобы на компьютере был установлен КриптоПро CSP и соответствующий сертификат для подписания.
Как упоминалось в обсуждении, программа КриптоАРМ также умеет создавать присоединенные подписи. При выборе опции "Присоединенная электронная подпись" и снятии галочки "сохранить подпись в отдельном файле", КриптоАРМ фактически создает криптографический контейнер (часто с расширением .p7m или .sgn), который содержит исходный файл и его цифровую подпись. Этот контейнер также является бинарным файлом.
Если требуется автоматизация процессов подписания через КриптоАРМ из 1С, то можно рассмотреть два пути:
csptest.exe, который позволяет вызывать его функции подписания с определенными параметрами. Для получения информации о доступных параметрах следует обратиться к документации КриптоАРМ.Для полного понимания задачи, давайте подробнее рассмотрим ключевые форматы присоединенных подписей, которые могут быть востребованы.
PKCS#7 (Cryptographic Message Syntax - CMS) является наиболее распространенным стандартом для криптографических сообщений. Он позволяет создавать как отсоединенные, так и присоединенные подписи. Когда мы говорим о присоединенной подписи в формате PKCS#7 (часто такие файлы имеют расширение .p7m, .sgn или просто .sig без указания "отсоединенности"), мы имеем в виду единый бинарный блок, который содержит:
Именно такой формат, вероятнее всего, ожидается принимающей стороной, если она упоминает "КриптоАРМ со снятой галочкой 'сохранить подпись в отдельном файле'". При попытке открыть такой файл в обычном текстовом редакторе мы увидим набор "иероглифов" или нечитаемых символов, поскольку это бинарный контейнер, а не чистый текст.
В ходе обсуждения также упоминался XMLDSig (XML Digital Signature). Это стандарт для электронной подписи, предназначенный специально для XML-документов. В этом случае подпись встраивается непосредственно в XML-структуру документа, обычно в виде нового элемента <Signature>. XMLDSig очень гибок и позволяет подписывать как весь XML-документ целиком, так и его отдельные части (элементы, атрибуты).
Однако, как было справедливо отмечено в обсуждении, XMLDSig не подходит для нашей задачи по нескольким причинам:
TXT), а не XML. Чтобы использовать XMLDSig, нам пришлось бы сначала преобразовать текстовый файл в XML-формат (например, заключив его содержимое в CDATA блок внутри XML-тега).Таким образом, хотя XMLDSig является мощным инструментом для подписания XML-документов, он не является решением для создания присоединенной подписи к простому текстовому файлу, когда принимающая сторона не поддерживает формат XML.
Подводя итог, мы выяснили, что создание присоединенной электронной подписи для текстовых файлов напрямую средствами 1С затруднено и часто невозможно из-за архитектурных особенностей формата TXT и ограничений встроенного функционала платформы.
Для успешного решения задачи, когда принимающая сторона ожидает единый файл, содержащий и текст, и подпись (формат PKCS#7/CMS), мы рекомендуем сосредоточиться на следующих подходах:
csptest.exe из состава КриптоПро CSP через командную строку 1С. Эта утилита позволяет создать присоединенную подпись в требуемом формате.CAdESCOM также может создавать присоединенные подписи. Однако это может потребовать более глубокого изучения ее документации и отладки параметров для избежания ошибок типа "Интерфейс не поддерживается".В любом из этих случаев, результирующий файл будет бинарным контейнером, который визуально не будет похож на исходный текстовый файл, но будет содержать его и цифровую подпись, что и является целью создания присоединенной ЭЦП.