Criptografia (HasSecurity)
O trait HasSecurity no Document fornece criptografia AES-256 através do engine Aes256Encryptor. O TCPDF-Next implementa exclusivamente o handler de segurança PDF 2.0 (AESV3, Revision 6, V5) — RC4 e AES-128 foram deliberadamente removidos. As senhas são normalizadas via SASLprep (RFC 4013) para tratamento adequado de Unicode, e a derivação de chave usa o Algoritmo 2.B (SHA-256/384/512 iterativo).
Referência Rápida
| Método | Descrição |
|---|---|
setProtection() | Habilitar criptografia AES-256 com permissões e senhas |
Habilitando Criptografia
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() retorna static, então encadeia com todos os outros métodos do Document.
$pdf->setProtection(
array $permissions = [], // Flags de permissão (veja tabela abaixo)
string $userPass = '', // Senha necessária para abrir o documento
string $ownerPass = '', // Senha para acesso irrestrito
);Senha do Usuário vs Senha do Proprietário
- Senha do usuário — o leitor deve inserir esta senha para abrir e visualizar o PDF. Quando vazia, o documento abre sem solicitação, mas as restrições de permissão ainda se aplicam.
- Senha do proprietário — concede acesso total ao documento, ignorando todas as restrições de permissão. Quando vazia, uma senha aleatória de 32 bytes é gerada internamente.
Ambas as senhas são normalizadas através do SASLprep (RFC 4013) antes da derivação de chave. Isso garante que senhas Unicode como "Pässwörd" sejam tratadas consistentemente em todos os visualizadores PDF.
Flags de Permissão
Passe qualquer combinação destas flags string no array $permissions:
| Flag | Descrição |
|---|---|
print | Permitir impressão (baixa resolução) |
modify | Permitir modificação de conteúdo |
copy | Permitir extração de texto e imagens |
annotate | Permitir adição de anotações |
fill-forms | Permitir preenchimento de campos de formulário |
extract | Permitir extração de acessibilidade |
assemble | Permitir inserção, rotação e exclusão de páginas |
print-highres | Permitir impressão em alta resolução |
Quando $permissions está vazio, todas as operações são restritas (senha do proprietário necessária para qualquer ação).
Criptografia Apenas do Proprietário
Para restringir permissões sem exigir senha para abrir:
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');O documento abre sem solicitação de senha, mas modificação, cópia e anotação são bloqueadas a menos que a senha do proprietário seja fornecida.
Arquitetura de Segurança
O TCPDF-Next aplica exclusivamente o padrão de criptografia PDF mais forte:
- Algoritmo: AES-256-CBC (AESV3), Revision 6, V5
- Comprimento da chave: 256 bits
- Sem legado: RC4 e AES-128 são deliberadamente removidos
Normalização de Senha SASLprep
A classe SaslPrep (RFC 4013) normaliza senhas com normalização Unicode NFKC, rejeita caracteres proibidos e aplica restrições de texto bidirecional. Isso garante hashes idênticos independentemente da plataforma ou método de entrada.
Derivação de Chave — Algoritmo 2.B
O Algoritmo 2.B do ISO 32000-2 deriva a chave de criptografia através de hashing SHA-256/384/512 iterativo (até 64 rodadas), fornecendo forte resistência contra ataques de força bruta.
Incompatibilidade com PDF/A
Criptografia não é permitida em documentos compatíveis com PDF/A. Se você tentar chamar setProtection() em um documento com modo PDF/A habilitado, uma PdfAException é lançada:
use Yeeefang\TcpdfNext\Core\Document;
// Isso vai lançar PdfAException
$pdf = Document::create()
->setPdfA(true)
->setProtection(permissions: ['print'], ownerPass: 'secret');
// -> throws PdfAException: "Encryption is not allowed in PDF/A documents"Se você precisa de conformidade arquivística e controle de acesso, considere usar assinaturas digitais com restrições de permissão.
Exemplo Completo
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');