Перейти к содержимому

Шифрование PDF с помощью AES-256 и настройка разрешений

Используйте этот рецепт, чтобы зашифровать документ с помощью AES-256. Вы задаёте пользовательский пароль, пароль владельца и битовую маску разрешений, ограничивающую допустимые операции. Рецепт основан на примере examples/22-protection.php.

Воспроизводимость — почему этот рецепт structural, а не bitwise. PDF-документ с AES-256 никогда не получается побайтово идентичным в разных запусках, даже при одинаковых входных данных и паролях. Перед выводом ключа шифрования файла стандартный обработчик безопасности ревизии 6 для каждого шифрования генерирует 16 новых случайных байтов (проверочные соли user/owner и соли ключа) с помощью стойкого генератора случайных чисел (ISO 32000-2 §7.6.4, алгоритм 2.B). AES-256-CBC использует случайный вектор инициализации для каждого объекта. Запись трейлера /ID также представляет собой массив из двух байтовых строк. Первый элемент этого массива — постоянный идентификатор, выведенный из файла в момент создания (ISO 32000-2 §14.4). Поэтому профиль воспроизводимости — structural: перед сравнением двух запусков тестовая обвязка приводит к каноническому виду соли и IV шифрования, порядок объектов и запись трейлера /ID, вместо того чтобы требовать невозможного побайтового совпадения.

  • Установлен Core: composer require nextpdf/core:^3.
  • Включено расширение PHP openssl, необходимое механизму шифрования AES-256.
  1. Создайте документ.
  2. Вызовите setEncryption() до addPage(). Механизм шифрования должен быть готов перед записью любого объекта содержимого.
  3. Передайте пользовательский пароль (требуется для открытия документа), пароль владельца (для полного доступа) и битовую маску разрешений.
  4. Добавьте содержимое и сохраните. Модуль записи шифрует тело каждого объекта.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Permission bits (ISO 32000-2, encryption dictionary P entry):
// bit 3 (4) allow printing
// bit 4 (8) allow content modification
// bit 5 (16) allow text extraction / copying
// bit 6 (32) allow annotation and form editing
// Grant printing only:
$permissions = 4;
$doc = Document::createStandalone();
$doc->setTitle('Encrypted Document');
// setEncryption() MUST run before addPage(). Order matters.
$doc->setEncryption(
userPassword: 'open-me',
ownerPassword: 'owner-secret',
permissions: $permissions,
);
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'This document is encrypted with AES-256.', newLine: true);
$doc->save(__DIR__ . '/encrypted.pdf');
echo "Wrote encrypted.pdf (AES-256, printing only)\n";
Wrote encrypted.pdf (AES-256, printing only)

При открытии encrypted.pdf программа просмотра запросит пароль. Пользовательский пароль откроет документ с ограниченным набором разрешений. Пароль владельца откроет его с полным доступом.

  • Порядок вызова. setEncryption() после addPage() не шифрует ранее добавленное содержимое задним числом. Всегда сначала настраивайте шифрование.
  • Пароль владельца по умолчанию. Если пароль владельца пуст, механизм повторно использует пользовательский пароль в качестве пароля владельца. Задавайте разные пароли, когда эти роли должны различаться.
  • Семантика разрешений: границы. Совместимые программы просмотра учитывают биты разрешений. Эти биты не защищены криптографически: программа просмотра, игнорирующая их, или инструмент, используемый с паролем владельца, может выполнять ограничиваемые операции. Рассматривайте разрешения как сигнал политики для совместимого программного обеспечения, а не как контроль доступа, устойчивый к настойчивому злоумышленнику.
  • Конфликт с PDF/A. PDF/A запрещает ключ трейлера Encrypt. Вызов setEncryption() для документа PDF/A при любом порядке вызовов выбрасывает исключение несовместимости. См. Шлюз соответствия PDF/A-4.
  • AES-256-GCM. useAesGcm() включает массовое шифрование GCM по ISO/TS 32003, если OpenSSL на узле или libsodium предоставляет этот шифр. В противном случае метод выбрасывает InvalidConfigException.
УтверждениеСпецификацияПунктreference_id (идентификатор ссылки)
Стандартный обработчик безопасности определяет алгоритм шифрования и длину ключа.ISO 32000-2§7.6
Запись P в словаре шифрования содержит биты разрешений.ISO 32000-2§7.6

Шифрование защищает конфиденциальность содержимого от сторон без пароля. Биты разрешений служат рекомендацией для программ просмотра и сами по себе не блокируют действия несовместимого инструмента.