Подписать PDF в Linux можно без Adobe Acrobat: есть свободные инструменты для создания криптографической подписи и её проверки. Важно различать два действия: нарисованная картинка с подписью — это просто изображение, а электронная подпись — криптографический объект, связанный с содержимым документа. Любое изменение уже подписанных байтов делает её недействительной. Ниже — практический маршрут: подготовка сертификата, подпись через PyHanko и JSignPdf, проверка через pdfsig и разбор ошибок валидации.

Что находится внутри подписи PDF

В PDF подпись хранится в специальном словаре. При подписании вычисляется хеш байтового диапазона файла, затем создаётся CMS/PKCS#7-структура с сертификатом и подписью, а в документ добавляется поле с этой структурой. Диапазон ByteRange показывает, какие байты покрыты подписью; поле подписи и последующие изменения в него не входят. Формат PAdES (ETSI EN 319 132) описывает профиль таких подписей и уровни с меткой времени и данными проверки.

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

Подготовка тестового сертификата

Для экспериментов подойдёт самоподписанный сертификат. Для рабочего документооборота используется сертификат, выданный доверенным удостоверяющим центром, а в России — квалифицированный сертификат; юридические требования зависят от соглашения сторон и вида документа, поэтому здесь мы ограничиваемся технической стороной.

openssl req -x509 -newkey rsa:3072 -keyout test.key -out test.crt -days 365 -nodes -subj "/CN=Test User/O=Example"
openssl pkcs12 -export -inkey test.key -in test.crt -out test.p12 -name "test"
chmod 600 test.key test.p12
openssl pkcs12 -info -in test.p12 -noout

Флаг -nodes оставляет ключ без пароля — только для тестов. Пароль на .p12 обязателен, а сам файл нельзя коммитить в репозиторий. Для реальной работы ключ лучше хранить в аппаратном токене или смарт-карте; тогда PyHanko и JSignPdf потребуют отдельного провайдера PKCS#11.

Подпись через PyHanko

PyHanko — библиотека и CLI для работы с PDF-подписями. Установите её изолированно через pipx, чтобы не смешивать зависимости с системным Python:

pipx install pyhanko
export PDF_PASS='пароль-от-p12'
pyhanko sign addsig --field Sig1 --p12 test.p12 --passphrase env:PDF_PASS \
  --reason "Согласование" --location "Москва" input.pdf signed.pdf
pyhanko sign validate --trust test.crt signed.pdf

Параметр --field задаёт имя поля подписи; если поля нет, оно создастся. --passphrase env:PDF_PASS читает пароль из переменной окружения, а не из истории команд. Для метки времени добавьте --tsa с адресом доверенного TSA-сервера; для долговременной проверки — данные OCSP/CRL, которые PyHanko умеет встраивать. Без метки времени подпись остаётся действительной, но после истечения сертификата доказать момент подписания сложнее.

Вариант с JSignPdf и Okular

Если нужен графический интерфейс, JSignPdf умеет и пакетный режим. Синтаксис зависит от версии, поэтому проверьте --help; типовая команда выглядит так:

java -jar JSignPdf.jar --help
java -jar JSignPdf.jar -kstore test.p12 -kspass "$PDF_PASS" \
  -kalias test -d signed/ input.pdf

Okular умеет добавлять и проверять подписи через меню работы с цифровыми подписями. Ему нужен сертификат с ключом в хранилище NSS; импорт .p12 можно сделать командой pk12util:

mkdir -p ~/.pki/nssdb
certutil -N -d sql:$HOME/.pki/nssdb --empty-password
pk12util -i test.p12 -d sql:$HOME/.pki/nssdb

После импорта сертификат появится в списке, и документ можно подписать без терминала. Для проверки чужих подписей в Okular достаточно открыть файл: программа покажет статус, но доверие к корневому сертификату всё равно нужно настроить отдельно.

Проверка подписи

Универсальный инструмент — pdfsig из пакета poppler-utils. Он показывает количество подписей, тип, имя подписавшего и результат проверки целостности:

pdfsig signed.pdf
pdfsig -dump signed.pdf
qpdf --check signed.pdf
pdfinfo signed.pdf | head -20

pdfsig проверяет, что байты документа не изменились после подписания, и проверяет сертификат. Если корневой сертификат не добавлен в хранилище NSS, статус может выглядеть как «не удалось проверить цепочку», хотя сама подпись корректна. Для самоподписанного сертификата это ожидаемо. qpdf --check полезен для проверки структуры файла, но не заменяет криптографическую валидацию.

Для проверки в скрипте удобен PyHanko: он возвращает ненулевой код при ошибке и умеет работать с доверенными корнями через --trust. Сравнивайте результаты двух инструментов: расхождение часто указывает на отсутствие промежуточного сертификата или на неверно выбранный профиль подписи.

Российская практика и ГОСТ

В российском документообороте чаще используют квалифицированную электронную подпись с сертификатом аккредитованного удостоверяющего центра и криптографией по ГОСТ Р 34.10-2012. Для PDF это означает поддержку соответствующего криптопровайдера: CryptoPro CSP и специализированный модуль или редактор, который умеет встраивать такую подпись в документ. Утилита cryptcp создаёт отделённую CMS-подпись файла, но не встраивает её в PDF; для встроенной подписи нужен инструмент с поддержкой ГОСТ и PAdES. Проверка выполняется тем же криптопровайдером либо сервисом, которому доверяет получатель. Юридические требования к формату и сертификату зависят от вида документа, поэтому техническую проверку стоит отделять от оценки юридической силы.

Типичные ошибки

  • Картинка вместо подписи. Изображение не защищает документ от изменений.
  • Правка после подписания. Любое изменение подписанных байтов делает подпись недействительной, даже если визуально документ тот же.
  • Нет цепочки сертификатов. Проверяющий не может построить путь до доверенного корня.
  • Истёк сертификат без метки времени. Подпись, сделанная в срок, но проверяемая позже, выглядит сомнительной.
  • Подпись в зашифрованном PDF. Некоторые инструменты требуют сначала снять пароль или поддерживают только определённые режимы шифрования.
  • Несколько подписей. Проверяйте каждую отдельно: действительность первой не гарантирует корректность последующих.

Итог

В Linux есть полный набор инструментов для PAdES-подписи и проверки PDF: PyHanko для сценариев и CI, JSignPdf и Okular для настольной работы, pdfsig и qpdf для контроля результата. Ключевой принцип — подписывать нужно криптографической структурой, а не изображением, и проверять цепочку сертификатов и метку времени. Чек-лист: защищённый ключ, корректный профиль подписи, доверенный корень у проверяющего, повторная проверка после любых правок и понятный журнал того, кто и когда подписал документ.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте