Шифрование (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 шифрование с разрешениями и паролями |
Включение шифрования
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.
$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 пустой, все операции ограничены (для любого действия требуется пароль владельца).
Шифрование только для владельца
Для ограничения разрешений без требования пароля для открытия:
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:
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"Если вам нужны и архивное соответствие, и контроль доступа, рассмотрите использование цифровых подписей с ограничениями разрешений.
Полный пример
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');