Artigo Técnico

PDF 2.0 com criptografia AES-GCM no Delphi: ISO/TS 32003

O PDFiumPas grava criptografia ISO/TS 32003 por meio de SaveAsEncrypted: defina Revision como erR7 e toda string e stream fica protegida com AES-256 em modo GCM, a cifra autenticada que o PDF 2.0 ganhou em 2023. Defina também EnableIntegrityProtection e o documento passa a carregar também um token PDF MAC autônomo, que ValidatePdfMac verifica do lado da leitura

Essas são duas proteções diferentes que as pessoas costumam confundir. O GCM autentica cada valor criptografado. O MAC autentica o documento como um todo. Você quer os dois, por motivos diferentes

O que o GCM adiciona que o CBC nunca ofereceu?

Autenticação do texto cifrado. O AES-256 em modo CBC, o esquema AESV3 da ISO 32000-2, mantém o conteúdo confidencial e não diz nada sobre se ele chegou sem modificações. O CBC é maleável de formas específicas e bem estudadas: um atacante que consegue inverter bits no texto cifrado produz mudanças previsíveis no texto plano do bloco seguinte, e nada no formato percebe isso

O GCM fecha essa brecha. Cada valor criptografado carrega uma tag de autenticação de 16 bytes, serializada por completo como a ISO/TS 32003 exige, e a decifragem falha em vez de retornar um texto plano alterado quando a tag não corresponde. Em termos de PDF, uma string ou stream adulterada em um documento AESV4 é um erro definitivo no ponto de uso, não um valor estranho que se propaga pela sua aplicação. O dicionário Encrypt marca isso com /CFM /AESV4 e V 6 / R 7, ao lado de uma entrada de extensões declarando /ExtensionLevel 32003 e /ExtensionRevision (:2023)

Três revisões, três ecossistemas

TPdfEncryptionRevision oferece erR5, erR6 e erR7, e a escolha é mais uma decisão de compatibilidade do que uma decisão criptográfica. R5 é o esquema AES-256 original, publicado como uma extensão do PDF 1.7, com um único hash de senha SHA-256, e abre essencialmente em qualquer coisa dos últimos quinze anos. R6 é a derivação de chave reforçada, padronizada na ISO 32000-2, usando a construção iterativa SHA-256/384/512 do algoritmo 2.B, e é o que um workflow atual de PDF 2.0 ou PDF/A-4 espera. R7 é a ISO/TS 32003, usando a mesma derivação 2.B com AES-GCM como cifra

O suporte dos leitores segue exatamente essa ordem, e o suporte a R7 ainda é escasso fora dos visualizadores mainstream atuais. Essa é a mesma troca que rege qualquer recurso do PDF 2.0: a opção mais nova é a melhor engenharia e o público mais estreito. Decida com base em quem vai precisar abrir o arquivo, e se essa resposta for "um sistema de registros que ninguém atualiza desde 2019", a resposta é R5, independentemente do que a política de segurança prefira

uses
  PDFium, FPdfEncrypt;

var
  Pdf: TPdf;
  Opts: TPdfEncryptOptions;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'quarterly-report.pdf';
    Pdf.LoadDocument;

    Opts := TPdfEncryptOptions.Default;
    Opts.UserPassword := 'open-secret';
    Opts.OwnerPassword := 'admin-secret';
    Opts.EncryptMetadata := True;
    Opts.Revision := erR7;                    // ISO/TS 32003 AESV4-GCM
    Opts.EnableIntegrityProtection := True;   // token PDF MAC autônomo

    if not Pdf.SaveAsEncrypted('quarterly-report.enc.pdf', Opts) then
      raise Exception.Create('Encrypted save failed');
  finally
    Pdf.Free;
  end;
end;

Por que um MAC de documento sobre uma cifra autenticada?

Porque as tags do GCM protegem os valores, não o arranjo dos valores. Toda string e stream em um documento AESV4 é autenticada individualmente, mas a tabela de referência cruzada, a numeração de objetos e o trailer são estrutura, não conteúdo criptografado. Um atacante não consegue forjar um stream, mas nada na cifra sozinha o impede de rearranjar para quais objetos o documento aponta, ou de emendar objetos de uma revisão anterior do mesmo arquivo

O token PDF MAC autônomo trata dessa camada. O PDFiumPas o deriva da chave de criptografia do arquivo com um /KDFSalt dedicado de 32 bytes registrado no dicionário Encrypt, de modo que a posse da senha é o que permite a um leitor confirmar o token. O resultado é uma única resposta para uma única pergunta: esse documento, como um todo, é o documento que foi escrito

var
  Pdf: TPdf;
  Mac: TPdfMacValidationResult;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.Password := 'open-secret';
    Pdf.FileName := 'quarterly-report.enc.pdf';
    Pdf.LoadDocument;

    Mac := Pdf.ValidatePdfMac('open-secret');
    case Mac.Status of
      pmvsValid:       ProcessDocument(Pdf);
      pmvsNotPresent:  ProcessWithWarning(Pdf);       // sem token neste arquivo
      pmvsInvalid:     Quarantine(Mac.MessageText);   // adulterado ou truncado
      pmvsUnsupported: RouteForManualReview(Mac.MessageText);
    end;
  finally
    Pdf.Free;
  end;
end;

Os quatro valores de status exigem quatro respostas diferentes, e reduzi-los a um booleano perde a distinção que importa. pmvsNotPresent significa que o arquivo simplesmente não tem token, o que descreve quase todo PDF criptografado escrito antes de 2024 e não é evidência de nada. pmvsInvalid significa que um token está presente e não se verifica, o que é um achado genuíno e deve interromper o processamento. pmvsUnsupported significa que o token existe em um formato que esse build não implementa, o que é uma lacuna de compatibilidade, não um ataque. Tratar "não presente" como "inválido" colocaria em quarentena todo o seu acervo antigo já no primeiro dia

O que a criptografia ainda não faz

Os flags de permissão continuam sendo o que sempre foram: um pedido ao software compatível, não um controle. Os bits /P da Tabela 22 da ISO 32000-1, que proíbem impressão ou extração, são respeitados por visualizadores bem-comportados e ignorados por todo o resto, e qualquer um que tenha a senha do usuário já tem o conteúdo decifrado em mãos. A criptografia é a fronteira; as permissões descrevem intenção dentro dela

Vale planejar para dois detalhes operacionais. Primeiro, criptografia e modificação posterior interagem: anexar uma atualização incremental a um documento criptografado tem regras próprias, abordadas em atualizações incrementais em PDFs criptografados, e um token MAC é uma declaração em nível de documento que um anexo descuidado vai invalidar. Segundo, a construção GCM usa um contador de IV determinístico, e o PDFiumPas gera uma exceção em vez de reutilizar um valor de contador caso esse espaço se esgote algum dia, porque a reutilização de nonce no GCM é catastrófica de uma forma que um wraparound silencioso esconderia

Escolhendo entre as três revisões na prática

Anote quem abre o arquivo, depois escolha. Para distribuição interna, onde todo leitor é um visualizador atual sob seu controle, R7 com proteção de integridade é a opção mais forte disponível, e não há motivo para não usá-la. Para documentos que saem da organização, R6 é o padrão defensável: está padronizado na ISO 32000-2, não em uma especificação técnica construída sobre ela, e o suporte é amplo. Para arquivos e consumidores legados, R5 é a única escolha que abre de forma confiável, e você deve registrar o porquê no mesmo lugar em que registra o restante da sua política de retenção

Seja qual for a escolha, verifique a saída em vez de confiar que a chamada teve sucesso. Reabra o arquivo criptografado, confira ValidatePdfMac, e confirme que a versão declarada é a que você espera, usando as verificações de conformidade de versão em conformidade exata de versão de PDF. Um checklist mais amplo de entrada para documentos não confiáveis está em auditoria de riscos de segurança em PDF

O PDFiumPas é um componente Delphi e Lazarus construído em torno do motor PDFium, com a pilha de criptografia do PDF 2.0 implementada nativamente em Pascal, de modo que AES-256, GCM e o token MAC não precisam de nenhuma DLL de criptografia externa. A API de criptografia está documentada na página do componente PDFium Delphi