Как добавить несколько визуальных штампов ЭЦП в PDF-файл в 1С, не нарушая валидность предыдущих подписей?

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

При автоматизации документооборота часто возникает задача последовательного подписания PDF-документа несколькими ответственными лицами. Основная сложность заключается в том, что по требованиям ГОСТ на документе часто должна присутствовать визуальная отметка (штамп) о совершенном подписании. Однако любое изменение файла (например, вставка картинки штампа) после наложения электронной подписи приводит к её повреждению. В этой статье мы разберем, как реализовать механизм добавления множественных штампов ЭЦП, используя штатные средства платформы 1С:Предприятие 8.3.

Понимание механизма работы подписей в формате PDF

Для начала проанализируем ситуацию: почему обычное редактирование PDF убивает подпись? Любая электронная подпись (ЭЦП) гарантирует неизменность документа. Если мы открываем файл как картинку, рисуем на нем штамп и сохраняем — контрольная сумма файла меняется, и первая подпись становится невалидной.

Решение кроется в использовании технологии присоединенной подписи внутри структуры PDF. Формат PDF поддерживает так называемое инкрементальное сохранение (Incremental Updates). Когда мы добавляем подпись через специализированные объекты 1С, платформа не перезаписывает файл целиком, а дописывает данные о новой подписи и её визуальном представлении в конец файла. При проверке программы (например, Adobe Reader или КриптоПро PDF) умеют «отматывать» состояние файла к моменту наложения каждой конкретной подписи, подтверждая валидность всех этапов подписания.

Использование объектов ОписаниеПодписиPDF и ЗаписьPDF

Для реализации многократного подписания в 1С используются объекты ОписаниеПодписиPDF и ЗаписьPDF. Рассмотрим подробнее, как подготовить структуру для подписания. Основная логика заключается в том, что штамп не рисуется отдельно, а является частью визуального представления самой подписи.

Разберем по шагам процесс добавления подписи со штампом:

  1. Создаем объект ОписаниеПодписиPDF.
  2. Настраиваем его параметры: имя подписи, местоположение штампа на странице, текст штампа (ФИО, сертификат, сроки).
  3. Используем метод ЗаписатьПодпись (или его асинхронный аналог) объекта ЗаписьPDF.

Проанализируем пример кода для формирования описания подписи:


ОписаниеПодписи = Новый ОписаниеПодписиPDF;
ОписаниеПодписи.Имя = "Подпись_" + ТекущийПользователь.Наименование;
ОписаниеПодписи.Страница = 1; // Указываем номер страницы, где будет штамп
ОписаниеПодписи.Лево = 50;    // Координаты штампа
ОписаниеПодписи.Низ = 100;
ОписаниеПодписи.Ширина = 150;
ОписаниеПодписи.Высота = 50;

// Указываем данные сертификата для визуализации в штампе
ОписаниеПодписи.Текст = "Документ подписан ЭЦП" + Символы.ПС + 
                         "Владелец: " + ФИОСотрудника + Символы.ПС +
                         "Сертификат: " + НомерСертификата;

Реализация процесса подписания

Теперь выясним, как правильно применить это описание к существующему файлу. Если документ уже содержит одну или несколько подписей, нам нужно открыть его для чтения и дозаписать новую подпись. Важно понимать, что при использовании ЗаписьPDF предыдущие подписи сохраняются, если вы правильно работаете с объектом.


Запись = Новый ЗаписьPDF;
// Открываем существующий файл, который уже может содержать подписи
Запись.Открыть(ПутьКФайлу);

// Добавляем новую подпись с использованием сертификата и описания
Запись.ЗаписатьПодпись(СертификатКриптографии, ОписаниеПодписи);

// Файл будет обновлен инкрементально, сохранив старые данные
Запись.Закрыть();

Особенности работы в веб-клиенте (асинхронность)

Как показывает практика, при работе в веб-клиенте часто возникают ошибки типа «Неправильный путь к файлу» или просто отсутствие реакции системы. Это связано с тем, что веб-браузеры жестко ограничивают синхронные операции с файловой системой. Разберем ситуацию: если в тонком клиенте синхронные методы работают, то для веб-клиента обязательно использование асинхронных методов.

Рассмотрим правильный подход для кроссплатформенной работы:


// Сначала асинхронно открываем PDF для чтения
Чтение = Новый ЧтениеPDF;
Ждать Чтение.ОткрытьАсинх(ПутьКФайлу);

// Затем подготавливаем запись и асинхронно записываем подпись
Запись = Новый ЗаписьPDF;
Ждать Запись.ОткрытьАсинх(ПутьКВыходномуФайлу);

// Используем асинхронный метод для наложения подписи
Ждать Запись.ЗаписатьПодписьАсинх(Сертификат, ОписаниеПодписи);

Важный нюанс: Если вы забудете использовать ОткрытьАсинх и примените только ЗаписатьПодписьАсинх, в веб-клиенте это может привести к непредсказуемым ошибкам или зависанию сессии без выдачи сообщения об ошибке.

Проверка сертификатов внутри PDF

После того как мы научились добавлять подписи, нам может потребоваться программно проверить их наличие и валидность. В 1С объект ЧтениеPDF позволяет получить коллекцию подписей документа. Однако здесь есть «подводный камень»: при обращении к свойствам сертификата напрямую из объекта подписи PDF, система может зависнуть.

Для надежной проверки рекомендуется использовать следующий алгоритм:

  1. Прочитать документ через ЧтениеPDF.
  2. Получить массив Подписи.
  3. Для каждой подписи извлечь данные, но проверку самого сертификата (его цепочки и статуса отзыва) выполнять через МенеджерКриптографии, передавая туда данные подписи как внешнюю структуру.

Рекомендации по позиционированию штампов

Чтобы штампы нескольких подписантов не накладывались друг на друга, мы рекомендуем заранее продумать сетку расположения. Посмотрим на возможные варианты решения:

Таким образом, использование объектов ОписаниеПодписиPDF и ЗаписьPDF в сочетании с асинхронными методами позволяет создавать сложные юридически значимые бизнес-процессы согласования документов в формате PDF, сохраняя визуальную наглядность и техническую валидность всех электронных подписей.

← На главную