Skip to content

Шифрование (HasSecurity)

Trait HasSecurity класса Document обеспечивает AES-256 шифрование через движок Aes256Encryptor. TCPDF-Next реализует исключительно обработчик безопасности PDF 2.0 (AESV3, Revision 6, V5) — RC4 и AES-128 намеренно удалены. Пароли нормализуются через SASLprep (RFC 4013) для корректной обработки Unicode, а получение ключа использует Алгоритм 2.B (итеративный SHA-256/384/512).

Краткий справочник

МетодОписание
setProtection()Включить AES-256 шифрование с разрешениями и паролями

Включение шифрования

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setProtection(
        permissions: ['print', 'copy'],
        userPass: 'reader-password',
        ownerPass: 'owner-secret-password',
    )
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->cell(0, 10, 'This PDF is AES-256 encrypted', newLine: true)
    ->save('encrypted.pdf');

setProtection() возвращает static, поэтому он объединяется в цепочку с любым другим методом Document.

php
$pdf->setProtection(
    array  $permissions = [],   // Флаги разрешений (см. таблицу ниже)
    string $userPass    = '',   // Пароль для открытия документа
    string $ownerPass   = '',   // Пароль для неограниченного доступа
);

Пароль пользователя vs пароль владельца

  • Пароль пользователя — читатель должен ввести этот пароль для открытия и просмотра PDF. Если пустой, документ открывается без запроса, но ограничения разрешений всё равно применяются.
  • Пароль владельца — предоставляет полный доступ к документу, обходя все ограничения разрешений. Если пустой, внутренне генерируется случайный 32-байтный пароль владельца.

Оба пароля нормализуются через SASLprep (RFC 4013) перед получением ключа. Это гарантирует, что Unicode-пароли вроде "Pässwörd" обрабатываются единообразно во всех PDF-просмотрщиках.

Флаги разрешений

Передайте любую комбинацию строковых флагов в массиве $permissions:

ФлагОписание
printРазрешить печать (низкое разрешение)
modifyРазрешить модификацию контента
copyРазрешить извлечение текста и изображений
annotateРазрешить добавление аннотаций
fill-formsРазрешить заполнение полей форм
extractРазрешить извлечение для доступности
assembleРазрешить вставку, поворот и удаление страниц
print-highresРазрешить высококачественную печать

Когда $permissions пустой, все операции ограничены (для любого действия требуется пароль владельца).

Шифрование только для владельца

Для ограничения разрешений без требования пароля для открытия:

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setProtection(
        permissions: ['print', 'fill-forms'],
        ownerPass: 'admin-password',
    )
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->cell(0, 10, 'Open freely, but only print and fill forms.', newLine: true)
    ->save('restricted.pdf');

Документ открывается без запроса пароля, но модификация, копирование и аннотирование заблокированы, пока не введён пароль владельца.

Архитектура безопасности

TCPDF-Next применяет исключительно сильнейший стандарт шифрования PDF:

  • Алгоритм: AES-256-CBC (AESV3), Revision 6, V5
  • Длина ключа: 256 бит
  • Никакого legacy: RC4 и AES-128 намеренно удалены

Нормализация паролей SASLprep

Класс SaslPrep (RFC 4013) нормализует пароли с Unicode-нормализацией NFKC, отклоняет запрещённые символы и применяет ограничения двунаправленного текста. Это обеспечивает идентичные хеши независимо от платформы или метода ввода.

Получение ключа — Алгоритм 2.B

Алгоритм 2.B по ISO 32000-2 получает ключ шифрования через итеративное хеширование SHA-256/384/512 (до 64 раундов), обеспечивая высокую устойчивость к атакам перебора.

Несовместимость с PDF/A

Шифрование не допускается в документах, соответствующих PDF/A. Если вы попытаетесь вызвать setProtection() для документа с включённым режимом PDF/A, будет выброшено исключение PdfAException:

php
use Yeeefang\TcpdfNext\Core\Document;

// Это вызовет PdfAException
$pdf = Document::create()
    ->setPdfA(true)
    ->setProtection(permissions: ['print'], ownerPass: 'secret');
// -> throws PdfAException: "Encryption is not allowed in PDF/A documents"

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

Полный пример

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setTitle('Confidential Report')
    ->setAuthor('Security Team')
    ->setProtection(
        permissions: ['print-highres', 'copy'],
        userPass: 'open-me',
        ownerPass: 'full-access-2026',
    )
    ->addPage()
    ->setFont('Helvetica', 'B', 18)
    ->cell(0, 15, 'Confidential Report', newLine: true)
    ->setFont('Helvetica', '', 12)
    ->multiCell(0, 6, 'This document is protected with AES-256 encryption. '
        . 'Readers can print and copy, but cannot modify or annotate.')
    ->save('confidential-report.pdf');

Распространяется по лицензии LGPL-3.0-or-later.