Skip to content

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étodoDescrição
setProtection()Habilitar criptografia AES-256 com permissões e senhas

Habilitando Criptografia

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() retorna static, então encadeia com todos os outros métodos do Document.

php
$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:

FlagDescrição
printPermitir impressão (baixa resolução)
modifyPermitir modificação de conteúdo
copyPermitir extração de texto e imagens
annotatePermitir adição de anotações
fill-formsPermitir preenchimento de campos de formulário
extractPermitir extração de acessibilidade
assemblePermitir inserção, rotação e exclusão de páginas
print-highresPermitir 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:

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');

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:

php
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

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');

Distribuído sob a licença LGPL-3.0-or-later.