В процессе автоматизации документооборота часто возникает потребность сделать электронную подпись (ЭП) наглядной. По умолчанию 1С часто создает отсоединенную подпись (файл с расширением .p7s), которая «лежит рядом». Однако для конечного пользователя гораздо удобнее видеть «синий штампик» непосредственно в теле PDF-файла, который к тому же является интерактивным (кликабельным) при открытии в Adobe Acrobat. Разберем, как реализовать такую задачу в «1С:Документооборот» (1С:ДО), используя как штатные средства, так и внешние инструменты.
Прежде чем переходить к коду, проанализируем ситуацию с технической точки зрения. Традиционный механизм 1С при использовании объекта МенеджерКриптографии создает подпись формата CMS/CAdES. Она не меняет структуру самого файла, а генерирует зашифрованный хэш в отдельном файле. Это неудобно для пересылки документа внешним контрагентам.
Для встраивания подписи в PDF существует стандарт PAdES (PDF Advanced Electronic Signatures). Он позволяет включить данные о подписи в структуру самого документа. Важным моментом здесь является «инкрементальное сохранение». Если мы просто «нарисуем» картинку штампа поверх PDF, мы изменим бинарные данные файла, что сделает любую предыдущую криптографическую подпись невалидной. Поэтому нам нужно использовать инструменты, которые умеют корректно работать со структурой PDF.
Если вы используете современную версию 1С:ДО (редакция 3.0 и выше), разработчики 1С уже внедрили функционал визуализации штампов. Рассмотрим, как это работает:
Однако стоит помнить, что штатный механизм в старых версиях (2.1) ограничен. Если переход на 3.0 невозможен, придется рассмотреть программные методы интеграции.
Рассмотрим ситуацию, когда у нас есть консольное приложение (например, на C# с использованием библиотеки iTextSharp или iText7), которое умеет принимать путь к файлу, сертификат и накладывать подпись. Это один из самых надежных способов добиться «кликабельности» штампа.
Для интеграции такого решения в 1С:ДО нам потребуется вмешаться в процесс подписания документа. Выясним причину, почему это лучше делать через переопределение общих модулей. Нам нужно найти место, где файл уже выбран для подписания, но еще не сохранен в базу как подписанный.
Пример логики вызова внешнего приложения из 1С:
Процедура ПодписатьФайлВнешнимМодулем(ПутьКФайлу, СерийныйНомерСертификата)
ПутьКПрограмме = "C:\SignTools\PdfSigner.exe";
ПараметрыЗапуска = СтрШаблон("""%1"" --file ""%2"" --cert ""%3"" --out ""%4""",
ПутьКПрограмме,
ПутьКФайлу,
СерийныйНомерСертификата,
ПутьКФайлу + "_signed.pdf");
// Используем ЗапуститьПриложение для вызова консольной утилиты
КодВозврата = 0;
ЗапуститьПриложение(ПараметрыЗапуска, , Истина, КодВозврата);
Если КодВозврата <> 0 Тогда
ЗаписатьЛогСобытий("Ошибка подписания PDF через внешний модуль");
Возврат;
КонецЕсли;
// Заменяем исходный файл подписанным
ПереместитьФайл(ПутьКФайлу + "_signed.pdf", ПутьКФайлу);
КонецПроцедуры
В данном примере мы используем синхронный запуск. Программа PdfSigner.exe выполняет встраивание объекта Signature в PDF. Важно, чтобы ваше внешнее решение поддерживало стандарт Incremental Update, иначе при наложении второй или третьей подписи (например, согласующим и утверждающим) предыдущие подписи будут «отваливаться» с ошибкой «Документ был изменен после подписания».
Посмотрим на ситуацию, когда нам нужно просто наложить визуальный слой, а криптографию оставить на совести 1С (хотя это менее «цивильный» способ). Утилита pdftk позволяет манипулировать слоями PDF.
Разберем алгоритм по шагам:
stamp или background в pdftk, чтобы объединить основной документ и штамп.Пример команды для pdftk:
pdftk original.pdf stamp stamp_layer.pdf output final_document.pdf
Если мы используем встроенную подпись, 1С:ДО может «потерять» ее из виду, так как она будет искать файл .p7s. Чтобы система понимала, что файл валиден, нам нужно проанализировать модуль ЭлектроннаяПодписьСлужебный.
Нам потребуется переопределить логику проверки наличия подписи. Вместо проверки наличия записи в регистре сведений КонтрольныеСуммыФайлов или наличия связанного объекта Справочник.Файлы.Подписи, мы можем реализовать вызов метода, который проверяет внутреннюю структуру PDF.
Проанализируем пример функции для встраивания в обработку проверки:
Функция ФайлИмеетВстроеннуюПодпись(ПутьКФайлу) Экспорт
// Если это PDF, мы можем прочитать последние байты файла
// на наличие маркера /ByteRange или /Contents
// Но надежнее использовать внешнюю компоненту
Результат = Ложь;
Попытка
Чтение = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.ANSI);
Текст = Чтение.Прочитать();
Если Найти(Текст, "/Type /Sig") > 0 Тогда
Результат = Истина;
КонецЕсли;
Исключение
Результат = Ложь;
КонецПопытки;
Возврат Результат;
КонецФункции
Важный момент: Прямой поиск текста в бинарном файле — это упрощенный метод. Для промышленного использования рекомендуется использовать Native API компоненты, которые умеют возвращать статус валидности подписи PDF без сохранения временных файлов.
При реализации любого из выбранных методов, обратите внимание на следующие аспекты:
Рассмотрев все варианты, можно сделать вывод: для 1С:ДО 2.1 оптимальным путем является использование внешней консольной утилиты на C# (iTextSharp) с вызовом через ЗапуститьПриложение в момент завершения бизнес-процесса подписания. Это обеспечит и визуальную красоту, и техническую корректность вложенных подписей.