Как стать автором
Обновить

Как реализовать пакетную подпись PDF-документов

Уровень сложностиСредний
Время на прочтение18 мин
Количество просмотров3.2K

Автоматическое подписание документов электронной подписью используют там, где требуется пакетная подпись документов без участия сотрудника. Это могут быть как небольшие сайты, например по продаже билетов в театр и музей, или порталы с онлайн-обучением при отправке сертификатов о прохождении курсов, так и крупные банковские приложения, например, при генерации выписок по счетам, форм договоров или квитанций. В ЕСИА, СМЭВ, ГИС ЖКХ и других государственных информационных системах также реализована автоматическая подпись.

В этой статье реализуем автоматическое подписание для PDF-файлов и добавим штамп «Документ подписан электронной подписью».

Чтобы лучше понять, как же в PDF-файл добавляется электронная подпись, начнем статью со структуры файла. Далее упомянем архивные форматы, т.к. часто в ЭДО важно не только подписать, но и обеспечить длительное хранение. В пункте про электронные подписи покажем, как она встраивается в структуру файла и перечислим некоторые продукты с поддержкой PAdES на ГОСТ-алгоритмах. И, наконец, перейдем к основной теме статьи — пакетная подпись PDF. Если вам интересна отдельная часть, то переходите по заголовкам:

Что хранится внутри PDF-файла?

Если вы откроете PDF-файл обычным текстовым редактором, а не специальной программой, то увидите набор бессмысленных символов, редкие проблески читаемого текста и знакомые конструкции вроде «%PDF-» или «%%EOF». Какую-то очевидную логику и структуру в контенте проследить сходу сложно. 

PDF ориентирован на отображение документа в неизменном виде на любых устройствах. Он сохраняет точное форматирование, шрифты, изображения и макет, что особенно важно для печати и презентаций. Если тот же XML чаще используют для обмена данными между приложениями и сервисами, то PDF — для представления готовых документов, которые читают и обрабатывают люди. Спецификация формата ISO 32000-2 открыта. И хоть она не маленькая (почти тысяча страниц), попробуем выделить основное. 

PDF-файл состоит из следующих элементов:

Начальная структура PDF-файла
Начальная структура PDF-файла

Заголовок

Началом файла является заголовок. Это текстовая строка, из пяти символов “%PDF-” и номера версии (сейчас допустимы значения от %PDF–1.0 до %PDF–2.0)

Для указания ридерам, что после заголовка идут бинарные данные, после заголовка указывается строка с комментарием не менее 4 байт, где каждый байт должен быть равен или больше 128 (0x80). Это обеспечивает корректную обработку с определением типа документа (текстовый или бинарный).

Спецификация допускает наличие произвольных данных до заголовка, они не влияют на обработчики и не учитываются при вычислении смещений (считаем их от знака процента в строке %PDF-).

Тело

Тело документа включает набор объектов, содержащих основной контент документа (изображения, текст и т.д.).

1 0 obj
% ...
endobj
2 0 obj
% ...
endobj

% ...

100 0 obj
% ...
endobj

Опишем восемь основных типов:

  1. Булево значение (Boolean): логические значения true или false.

  2. Число (Numeric): целое или вещественное число со знаком (опционально). Недесятичные основания или экспоненциальная запись не поддерживаются.
    Примеры: 42, 3.14, -67.7, +36,6. 

  3. Строка (String objects): текстовая строка длиной 0 и более байт. Строки оборачивают в круглые скобки (текстовая строка) или в треугольные (шестнадцатеричная строка). Текстовые строки могут записываться в несколько линий с переносом.
    Примеры: (Example), (), <4841425220544F5254>. 

  4. Имя (Name): начинается с символа / и используется для ключей. Содержит последовательность любых символов, кроме Null. Обычно не используются как текст для отображения.
    Примеры: /Type, /Name, /123.654.

  5. Массив (Array): Коллекция элементов различных типов, записанных в квадратных скобках. Поддерживаются только одномерные массивы, но допускается вкладывать одни массивы в другие с любой глубиной.
    Пример: [1 false (Example) 2.13].

  6. Словарь (Dictionary): пара «ключ-значение», заключенная в << и >>. Ключ должен быть представлен типом Name и быть уникальным в одном словаре. Значение может быть любого типа (в том числе другим словарем).
    Пример:  

    << /Key /Value
    /Subdictionary <<
    /Item0 (Example) /Item2 true
    >>
    >>

  7. Поток (Stream): последовательность байт любой длины, заключенных между stream и endstream, записанных после словаря. Например, поток может содержать текст, изображения или шрифты.

  8. Null: ключевое слово null, представляющее отсутствие значения. Если null используется как значение в словаре, то это соответствует пропуску записи.

Таблица перекрестных ссылок

Таблица перекрестных ссылок нужна для быстрого доступа к объектам в файле, обходясь без чтения всего файла.  Это похоже на «карту объекта» внутри PDF. Таблица представляет собой набор строк. Может быть в виде потока (stream).

Она состоит из записей формата:

nnnnnnnnnn ggggg <n | f> eol
  • Первые 10 символов: смещение объекта в байтах от начала документа.

  • Следующие 5 символов: номер поколения (или генерации).

  • Буква n или f: используется (n) или свободен (f).

  • eol — символ конца строки, должен быть представлен двумя символами.

Допускается два способа обозначения записей. Основной механизм использует связанный список: каждая свободная запись указывает на следующую, а первая запись (объект 0, головной) всегда свободна и имеет номер поколения 65 535, являясь началом списка. Последняя запись (хвост) ссылается обратно на объект 0.

Второй механизм позволяет другим свободным записям ссылаться на объект 0 с номером поколения 65 535, даже если они не входят в связанный список. Все объекты, кроме нулевого, изначально имеют номер поколения 0. При удалении объекта его запись помечается как свободная, добавляется в список, и ее номер поколения увеличивается на 1 для будущего использования. Максимальный номер поколения — 65 535; при его достижении запись больше не используется. Таблица должна содержать записи для всех номеров объектов от 0 до максимального, даже если некоторые объекты отсутствуют в файле.

xref
0 6
0000000001 65535 f
0000000018 00000 n
0000000091 00000 n
0000000000 00009 f
0000000321 00000 n
0000000543 00000 n

Пример: Таблица описывает 6 объектов, где с индексом 0 — удаленный, 1 — начинается с 18 байта, 2 — начинается с 91 байта, 3 — удаленный, 4 — начинается с 321 байта и 5 — начинается с 543 байта.

xref
0 1
0000000000 65535 f
2 1
0000011625 00000 n
13 2
0000025675 00002 n

25 1
0000026725 00000 n
32 1
0000025924 00000 n

Пример: Таблица содержит 5 объектов, где первый с индексом 0 — удаленный, с индексом 2 — начинается с 11625 байта, с индексом 13 — начинается с 25675 байта и имеет номер генерации равный 2, с индексом 25 — начинается с 264725 байта, с индексом 32 — начинается с 25924 байта.

Трейлер

Трейлер служит своеобразным «содержанием». Он помогает ридеру мгновенно найти нужные объекты и ускоряет открытие документа.

Трейлер используется, чтобы быстро находить таблицу ссылок и некоторые специальные объекты. PDF-документ читается с конца, где последняя строка должна включать маркер %%EOF. Перед ним идут две строки — startxref и смещение в байтах до начала таблицы ссылок. Перед startxref находится словарь трейлера.

Структура трейлера:

trailer 
  <<
    key1 value1
    key2 value2
    ...

    keyN valueN
  >>
startxref 
Byte_offset_of_last_cross-reference_section 
%%EOF 

Трейлер включает ключи:

  • /Size: количество записей в таблице.

  • /Prev: ссылка на предыдущий раздел перекрестных ссылок.

  • /Root: ссылка на корневой объект.

  • /Info: опционально, ссылка на метаданные документа.

Трейлер завершается ключевым словом startxref, за которым следует смещение кросс-референс таблицы.

Пример минимального файла

Рассмотрим следующий пример файла:

%PDF-2.0

1 0 obj

<< /Type /Catalog /Pages 2 0 R >>

endobj

2 0 obj

<< /Type /Pages /Kids [3 0 R] /Count 1 >>

endobj

3 0 obj

<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R >>

endobj

4 0 obj

<< /Length 44 >>

stream

BT

/F1 24 Tf

100 700 Td

(HABR) Tj

ET

endstream

endobj

xref

0 5

0000000000 65535 f 

0000000009 00000 n 

0000000056 00000 n 

0000000111 00000 n 

0000000219 00000 n 

trailer

<< /Size 5 /Root 1 0 R >>

startxref

478

%%EOF

Давайте разберем основные элементы этого файла:

  1. Заголовок %PDF-2.0 указывает, что файл соответствует версии 2.0.

  2. Объект 1 0 obj является корневым каталогом документа и содержит ссылку на объект 2 0 R, который описывает страницы.

  3. Объект 2 0 obj — это объект страниц, который ссылается на объект 3 0 R, представляющий первую страницу.

  4. Объект 3 0 obj описывает страницу, включая ее размеры (/MediaBox) и содержимое (/Contents 4 0 R).

  5. Объект 4 0 obj содержит поток данных (stream), включающий команды для отрисовки текста «Potato».

  6. Кросс-референс таблица (xref) указывает на смещения всех объектов в файле.

  7. Трейлер содержит информацию о корневом каталоге и размере таблицы.

Как вносятся изменения в PDF-файл?

Формат PDF позволяет вносить изменения в документ без полной перезаписи файла. Этот механизм называется инкрементальным обновлением (incremental update) и представляет собой процесс добавления новых данных в конец существующего файла. Вместо удаления старых данных новые объекты просто добавляются в конец файла, создается новая таблица перекрестных ссылок и обновляется трейлер. Такой подход не только экономит время при сохранении изменений, но и делает возможным редактирование в сценариях, когда перезапись исходного файла недоступна (например, при работе с документами через HTTP или OLE-встраивание в Windows).

По спецификации при инкрементном обновлении создается новая секция с изменениями, которая включает обновленные объекты, новую таблицу перекрестных ссылок (xref) и трейлер. При этом старые объекты не удаляются, а помечаются как неактивные.

Инкрементальное обновление PDF
Инкрементальное обновление PDF

Пример: если в документ добавляется новая аннотация, она записывается как новый объект, а затем обновляется страница, к которой она относится. В xref-таблице указываются смещения этих объектов в файле.

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

  7 0 obj<</Type /Annot

   /Subtype /Text

   /Rect [175 720 175 720]

   /Contents (Hello Annotation!)

   /Open true>>

   endobj

Далее обновляется страница, к которой добавляется ссылка на аннотацию:

   3 0 obj<</Type /Page

   /Parent 2 0 R

   /Resources 4 0 R

   /MediaBox [0 0 500 800]

   /Contents 6 0 R

   /Annots [7 0 R]>>

   endobj

Наконец, создается новая xref-таблица, которая указывает смещения новых объектов, и добавляется новый trailer:

   xref

   0 1

   0000000000 65535 f

   3 1

   0000000744 00000 n

   7 1

   0000000631 00000 n
trailer <</Size 8 /Root 1 0 R /Prev 406>>

Так выглядит указание на новую таблицу xref и завершение файла:

   startxref

   863

   %%EOF

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

Как подготовить документ к архивному хранению?

PDF рассчитан на одинаковое отображение документов на всех устройствах. Но когда речь идет о долгосрочном хранении, таких характеристик недостаточно. Для архивирования требуется не только точное сохранение содержимого, но и гарантии, что документ будет доступен для чтения через десятилетия независимо от используемого программного обеспечения или оборудования. Именно для таких целей и были созданы архивные форматы PDF/A.

Стандарт для архивного хранения

PDF/A — это подмножество формата PDF, созданное для обеспечения долговременного хранения электронных документов. Он исключает функции и возможности, которые могут затруднить или сделать невозможным доступ к файлу в будущем. Впервые архивный формат был стандартизирован как ISO 19005 в 2005 году.

Цель этого формата — сохранить все данные, необходимые для отображения документа, внутри самого файла. Это включает шрифты, цветовые профили, метаданные и даже мультимедийный контент (в определенных случаях).

Основные отличия PDF/A от стандартного PDF

PDF/A налагает ряд ограничений на использование функций стандартного PDF. Некоторые особенности:

  1. Встраивание шрифтов:

    Все шрифты, используемые в документе, должны быть встроены. Это предотвращает проблемы с отображением текста, если шрифт отсутствует на устройстве пользователя.

  2. Запрет шифрования:

    Не допускает шифрование или защиту паролем, так как это затрудняет доступ к документу в будущем.

  3. Однозначность цветов:

    Все цвета в документе должны быть описаны с использованием цветовых профилей, таких как sRGB или CMYK.

  4. Запрет внешних ссылок:

    Документ не должен ссылаться на внешние ресурсы, чтобы избежать потери данных при недоступности этих ресурсов.

  5. Метаданные:

    Требует обязательного использования метаданных в формате XMP (Extensible Metadata Platform).

  6. Поддержка только статического контента:

    Запрещено использование JavaScript, мультимедиа и других интерактивных элементов.

  7. Определенный порядок слоев и прозрачности:

    Для упрощения рендеринга в будущем все визуальные элементы должны быть однозначно упорядочены.

Уровни соответствия PDF/A

PDF/A состоит из нескольких частей, каждая из которых расширяет и уточняет стандарт:

  • PDF/A-1: базовый уровень (основан на PDF 1.4).

    Подходит для текстовых документов без сложных элементов вроде прозрачности.

  • PDF/A-2: поддержка новых функций (PDF 1.7).

    Добавлена прозрачность, сжатие JPEG 2000 и возможность объединять файлы в один PDF/A.

  • PDF/A-3: поддержка вложений.

    Позволяет встраивать произвольные файлы (например, XML или CSV) внутрь PDF/A.

Кроме того, PDF/A делится на уровни соответствия:

  • a (accessibility): требует полной доступности, включая семантические теги.

  • b (basic): гарантирует только визуальную целостность.

  • u (unicode): обеспечивает сохранение всех текстовых данных в Unicode.

Зачем использовать PDF/A?

PDF/A незаменим в тех случаях, когда важно обеспечить долгосрочное хранение документов с сохранением их юридической значимости и информационной ценности. Основные сценарии применения:

  1. Юридические документы: Контракты, соглашения, судебные акты.

  2. Архивы организаций: Корпоративные отчеты, научные исследования, проекты.

  3. Государственные документы: Законы, постановления, исторические архивы.

  4. Медицинские записи: Истории болезней, результаты анализов.

Чем проверить соответствие PDF/A?

Для проверки документов на соответствие PDF/A используются специальные инструменты. Можно пользоваться встроенным в Adobe Acrobat. Если выбирать из opensource, то одним из наиболее надежных решений является veraPDF. Это бесплатное и открытое ПО, разработанное в рамках проекта Open Preservation Foundation и поддерживаемое Европейской комиссией.

Основные возможности veraPDF:

  • Проверка соответствия всем частям стандарта ISO 19005.

  • Отчеты о нарушениях в структуре PDF/A.

  • Поддержка командной строки для интеграции в автоматизированные процессы.

Пример: проверка PDF/A с помощью veraPDF и формированием отчета в html формате

verapdf.bat --format html "D:\Simple PDF 2.0 file.pdf" >> "D:\Simple PDF 2.0 file.report.html"

Инструмент анализирует файл, выявляет несоответствия и предлагает рекомендации по их устранению. Если документ соответствует стандарту, будет выведено подтверждение.

Результат проверки файла в veraPDF
Результат проверки файла в veraPDF

Какие регламенты по использованию PDF/A есть в России?

Федеральная налоговая служба (ФНС) Российской Федерации утвердила использование формата PDF/A-3 для подачи договорной документации в электронном виде. Данное решение зафиксировано в Приказе ФНС России от 24.03.2022 № ЕД-7-26/236@, который начал действовать спустя 30 дней после официальной публикации.

Формат PDF/A-3 был принят для обеспечения долгосрочного хранения электронных документов и их совместимости с различными программными платформами. PDF/A-3 позволяет объединить визуальное отображение документа (для удобства восприятия человеком) и структурированные данные в формате XML (для автоматизированной обработки). Это важно для договоров, соглашений, протоколов разногласий и других документов, требующих высокой точности и юридической значимости.

Ключевые характеристики формата:

  1. Единый файл-контейнер: содержится как визуальная часть (для чтения), так и вложенный XML-файл (для автоматической обработки).

  2. Электронная подпись: Документы заверяются электронной подписью, соответствующей требованиям Федерального закона № 63-ФЗ «Об электронной подписи».

  3. Универсальность: Формат поддерживает различные типы договорных документов, включая договоры, протоколы разногласий и дополнительные соглашения.

Про электронные подписи в PDF

Мы уже познакомились с базовой структурой файла и с инкрементальным обновлением, теперь рассмотрим как это использовать при добавлении подписи внутрь документа.

А зачем вообще использовать электронную подпись? ЭП обеспечивает:

  1. Проверку целостности документа — гарантия, что документ не изменялся после подписания.

  2. Подтверждение личность подписавшего с использованием инфраструктуры открытых ключей (PKI).

  3. Контроль изменений и ограничение разрешений после подписания.

Электронная подпись интегрирована в PDF таким образом, что не требует отдельного файла. Подписанный так документ можно открывать для чтения в любом доступном ПО. 

PAdES (PDF Advanced Electronic Signatures) — это стандарт для создания и проверки электронных подписей в документах формата PDF. Он был разработан на основе спецификаций ETSI (European Telecommunications Standards Institute) и обеспечивает высокий уровень безопасности и юридической значимости подписей. PAdES поддерживает различные уровни подписей, включая долгосрочные, что позволяет гарантировать долговечность и достоверность подписанных документов даже спустя годы.

Типы подписей в PDF

Стандарт поддерживает два типа электронных подписей с использованием сертификатов :

  1. Заверяющая подпись или подпись для утверждения (Approval Signature):

    • Позволяет многократное подписание.

    • Может использоваться для заполнения форм.

  2. Сертифицирующая подпись (Certification Signature):

    • Должна быть одна в документе и при этом ставится первой.

    • Ограничивает дальнейшие изменения (например, разрешая только аннотации или добавление подписей).

    • Может быть как видимой, так и без отображения на странице.

Основная структура подписей в PDF

Электронная подпись в PDF хранится в специальной структуре, называемой словарем подписей (Signature Dictionary). Эта структура содержит метаданные подписи и ссылки на связанные данные:

  • Ключ /Contents: хранит значение подписи — закодированный объект PKCS#7, включающий хеш документа, зашифрованный закрытым ключом подписанта.

  • Ключ /ByteRange: указывает, какие байты документа были включены в хеш при создании подписи. Это массив из четырех чисел, определяющий диапазоны данных (до и после области, зарезервированной для подписи).

  • Ключ /Filter: указывает, какой обработчик подписей использовался.

  • Ключ /SubFilter: уточняет формат и алгоритм подписи.

Пример структуры подписей:

  /Type /Sig
  /Filter /Adobe.PPKLite - Используемый метод подписи 
  /SubFilter /adbe.pkcs7.detached - Формат подписи
  /ByteRange [0 840 960 240] - Диапазон для хеширования
  /Contents <...> Поле для самой подписи (резервируем место)
  /Reason (Approval of contract) - Причина подписи (опционально)
  /M (D:20250128120000Z) - Дата подписи
  /ContactInfo (support@example.com)

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

Добавление электронной подписи состоит из нескольких этапов:

  1. Новая секция обновления добавляется в документ (то самое инкрементальное обновление).

  2. Добавляем изображение в документ для XObject Form связанного с подписью (если требуется визуализация).

  3. Резервируем пространство и выполняем промежуточное сохранение документа перед подписанием

    1. Резервируем пространство в поле Contents. Значение этого поля не может быть меньше значения подписи, поэтому выделяем с запасом (неиспользуемая часть будет заполнена нулями).

    2. Так как мы не знаем, где окажется Contents после сохранения, то нам потребуется также зарезервировать пространство для ByteRange.

      Массив /ByteRange состоит из четырех чисел. Первое число в каждой паре — это смещение (от начала, начиная с 0) начала потока байтов, которые должны быть включены в хэш. Второе число — это длина этого потока. Две пары определяют две последовательности байтов, которые определяют, что должно быть хэшировано.

    Перед подписанием ByteRange имеет вид: /ByteRange [          0          0          0          0]

    3. После сохранения нужно определить начало и конец содержимого Contents (значением между < >) и обновить значения для ByteRange.

    /ByteRange [          0       3291       7935       4218]

  4. Получим подписываемый контент с использованием имеющихся значений ByteRange.

  5. Вызываем подпись полученного контента с помощью обработчика (отдельного модуля).

  6. Сохраняем полученную подпись в поле Contents.

    Пример готовой структуры Contents: /Contents <3082025B06092A864886F70D010702A082024C30820248...>

Подписываемые данные и встраивание подписи внутрь PDF
Подписываемые данные и встраивание подписи внутрь PDF

Продукты и сервисы с поддержкой PAdES на ГОСТах

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

Продукты

КриптоАРМ — это решение для работы с электронной подписью и шифрованием данных, включая подписание PDF-документов. Продукт поддерживает различные форматы подписей, включая CAdES и PAdES по ГОСТам. Можно подписывать документы встроенной, присоединенной или отсоединенной подписью на выбор. Есть сертификация pdf документа, можно разметить несколько областей для подписания, конвертировать в архивный формат. Есть поддержка разных ОС (Windows, Linux, macOS). В режиме пакетной подписи может подписать файлы любого формата. Реализована визуализация электронной подписи — добавление изображения штампа подписи. Для серверного использования, под автоматизацию, есть отдельное исполнение  — КриптоАРМ Server.

КриптоПро PDF — это модуль для Adobe Acrobat и Reader, предназначенный для создания и проверки электронных подписей на ГОСТ-алгоритмах. Гибкая настройка внешнего вида штампа. Есть пакетная подпись (только в Adobe Acrobat Standard или Adobe Acrobat Pro). Работает только на Windows.

ContentReader PDF — это специализированное приложение для просмотра и работы с PDF-документами, включая функции подписания и проверки электронных подписей, что позволяет использовать его для работы с юридически значимыми документами. Из интересных дополнительных функций: возможность извлечь текст из отсканированных документов.

CryptExpert — это программное обеспечение для создания и проверки электронных подписей. В CryptExpert можно подписывать PDF-файлы как встроенной подписью, так и в виде отдельного файла.

Окуляр ГОСТ — приложение создано на основе свободного приложения Okular. Дополнено поддержкой ЭП (использует КриптоПро). Работает на Windows и Linux.

Сервисы

sign.kloud.one — это сервис для проверки электронных подписей, в том числе и стандарта PAdES.Для PDF-документов после проверки доступна возможность скачать копию файла с визуальным штампом о сведениях подписи. Интересная опция: возможность улучшить стандарт подписи. Исходный код открыт и доступен по ссылке.

КриптоПро SVS 2.0 — это программно аппаратный комплекс для проверки сертификатов и электронных подписей. Решение позволяет проверять подписи, созданные с использованием различных стандартов, таких как CAdES, XAdES и PAdES, а также поддерживает проверку сертификатов на соответствие требованиям регулятора.

Миг24 — это сервис для формирования разных видов подписей (открепленная подпись, прикрепленная подпись, встроенная). Решение поддерживает стандарты ГОСТ. Есть возможность визуализировать подпись.

Пакетная подпись PDF

После знакомства со структурой файла и основами PAdES переходим к практической части – настройке автоматической подписи документов на сервере.

Чтобы не подписывать некую сову, предположим, что мы — бюро кредитных историй (это не так, все совпадения случайны). На Госуслугах начала работать услуга по самозапрету кредитования. Наша задача — отправить клиенту решение в читаемом виде и подписанное УКЭП. Собравшись и обсудив задачу с командой, принято решение — не отправлять PDF с картинкой про подпись, а использовать PAdES.

Т.к. для подписания нам в любом случае потребуется сертификат, необходимо его получить. И нам, как БКИ, стоит обратиться с этим в УЦ Центрального Банка. Сертификат нам выдали, но в сведениях о субъекте там нет ни имени руководителя, ни хотя бы сотрудника. Ошибка? Нет! Это так называемый обезличенный сертификат, который и нужен для автоматического подписания на сервере.

Что такое обезличенная электронная подпись?

Обезличенная ЭП – это цифровая подпись, созданная на основе сертификата, в котором отсутствуют персональные данные владельца. Такой формат используется юридическими лицами и индивидуальными предпринимателями (для ИП в сертификате могут быть указаны их данные). По своей сути, эта подпись выполняет роль организационной печати, упрощая автоматизацию документооборота в цифровых системах. Важное отличие – сертификат обезличенной подписи не привязан к конкретному сотруднику. Его выдают для информационных систем, в которых автоматизирован процесс подписи и шифрования.

В России обезличенные сертификаты для информационных систем выдаются несколькими государственными структурами:

  • ФНС России выпускает квалифицированные сертификаты операторам информационных систем.

  • Центробанк РФ выпускает такие сертификаты для организаций, работающих в рамках ч. 1 ст. 76.1 Закона о Центральном банке.

  • Федеральное казначейство выдает сертификаты для органов государственной власти.

Примеры кода по автоматизации подписи PDF

Следующий шаг нашей команды за аналитиками и разработкой. Они подбирают подходящее решение для пакетной подписи PDF. Из условий: модуль можно использовать в node.js и упаковать всё решение в микросервис, а подпись конечно должна быть реализована на ГОСТ-алгоритмах. В качестве подходящего варианта для работы со структурой файла, решили остановится на  модуле с открытым кодом — trusted-pdf (из состава КриптоАРМ Server, о нем упоминали ранее в списке продуктов).

Модуль выбран, сертификат есть, переходим к примерам кода. В качестве исходного документа возьмем пример файла из репозитория от PDF Association.

Для простоты тут приведем псевдокод реализации (если будет интересно, напишите, выложим полные примеры):

Добавление невидимой подписи

import * as fs from "node:fs";
import * as pdf from "@trusted-pdf/pdf";
import * as pdfSign from "@trusted-pdf/sign";

const buf = fs.readFileSync(path/Simple PDF 2.0 file.pdf);
const doc = new pdf.Document();

doc.read(buf);

const sign = new pdfSign.Sign(doc);

sign.addSignatures({
  name: "signature 1",
  page: 1,
});

doc.save();

Добавление подписи со штампом

import * as fs from "node:fs";
import * as pdf from "@trusted-pdf/pdf";
import * as pdfSign from "@trusted-pdf/sign";

const buf = fs.readFileSync(path/to/input.pdf);
const doc = new pdf.Document();

doc.read(buf);

const sign = new pdfSign.Sign(doc);

sign.addSignatures({
  name: "signature 1",
  page: 1,
  rectangle: {
	x: 20,
	y: 750,
	height: 150,
	width: 50,
  },

  stream: Buffer.from("0.5 g\n0 0 150 50 re\nf"),
});

doc.save();

Подписание внешним модулем

import * as fs from "node:fs";
import * as pdf from "@trusted-pdf/pdf";
import * as pdfSign from "@trusted-pdf/sign";

const buf = fs.readFileSync(path/to/input.pdf);

const doc = new pdf.Document();

doc.read(buf);

const sign = new pdfSign.Sign(doc);
const sig = sign.getSignature("signature 1");

await sig.sign({
  contentLength: 1300,
  onUpdate: async () => {
	sig.dict
    	.get("V", PdfDictionary)
    	.set("Name", doc.createLiteral("Иванов И.И."));
  },

  onSign: async (content) => {

	// Подписание Content и формирование блока подписи в формате CMS
    // Выполняется в отдельном модуле

	return new Uint8Array(cms);
  },
});

doc.save();

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

Результат проверки на тестовом сервисе КриптоПро SVS
Результат проверки на тестовом сервисе КриптоПро SVS
Проверка подписанного PDF-файла в КриптоАРМ
Проверка подписанного PDF-файла в КриптоАРМ

Вывод

Формат PDF — это не просто удобный способ представления документов для чтения или печати, но и хороший инструмент для интеграции с системами электронного документооборота, архивного хранения и электронной подписи.

Мы рассмотрели основные элементы PDF-файла, требования архивного стандарта и возможности использования ГОСТ-алгоритмов для подписи документов (с примерами продуктов и сервисов). Надеемся, что представленные материалы помогут вам глубже понять формат и успешно применять его в ваших проектах.

P.S. Если какую-то тему стоит раскрыть подробно отдельно, пишите в комментариях.

Теги:
Хабы:
Всего голосов 12: ↑12 и ↓0+14
Комментарии19

Публикации