O PDFiumPas escreve encriptação ISO/TS 32003 através de SaveAsEncrypted: defina Revision como erR7 e todas as strings e fluxos ficam protegidos com AES-256 em modo GCM, a cifra autenticada que o PDF 2.0 recebeu em 2023. Defina também EnableIntegrityProtection e o documento passa também a transportar um token PDF MAC autónomo, que ValidatePdfMac verifica do lado da leitura
São duas proteções diferentes que as pessoas costumam confundir. O GCM autentica cada valor encriptado. O MAC autentica o documento como um todo. Quer ambas, por razões diferentes
O que acrescenta o GCM que o CBC nunca ofereceu?
Autenticação do texto cifrado. O AES-256 em modo CBC, o esquema AESV3 na ISO 32000-2, mantém a confidencialidade do conteúdo e nada diz sobre se este chegou sem alterações. O CBC é maleável de formas específicas e bem estudadas: um atacante capaz de inverter bits no texto cifrado produz alterações previsíveis no texto simples do bloco seguinte, e nada no formato o deteta
O GCM resolve isso. Cada valor encriptado transporta uma etiqueta de autenticação de 16 bytes, serializada na íntegra conforme a ISO/TS 32003 exige, e a desencriptação falha em vez de devolver texto simples alterado quando a etiqueta não corresponde. Em termos de PDF, uma string ou fluxo adulterado num documento AESV4 é um erro definitivo no ponto de utilização, e não um valor estranho que se propaga na sua aplicação. O dicionário Encrypt assinala isto com /CFM /AESV4 e V 6 / R 7, juntamente com uma entrada de extensão que declara /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. A R5 é o esquema AES-256 original, publicado como extensão do PDF 1.7, com um único hash de palavra-passe SHA-256, e abre em praticamente tudo dos últimos quinze anos. A R6 é a derivação de chave reforçada normalizada na ISO 32000-2, usando a construção iterativa SHA-256/384/512 do algoritmo 2.B, e é o que um fluxo de trabalho PDF 2.0 ou PDF/A-4 atual espera. A 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 à R7 ainda é reduzido fora dos visualizadores atuais mais comuns. É a mesma compensação que rege qualquer funcionalidade do PDF 2.0: a opção mais recente é a melhor engenharia e o público mais restrito. Decida em função de quem tem de abrir o ficheiro, e se essa resposta for "um sistema de registos que ninguém atualiza desde 2019", a resposta é R5 independentemente do que a política de segurança preferir
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;
Porquê um MAC de documento sobre uma cifra já autenticada?
Porque as etiquetas GCM protegem os valores, não a disposição dos valores. Cada string e fluxo num documento AESV4 é autenticado individualmente, mas a tabela de referência cruzada, a numeração de objetos e o trailer são estrutura, não conteúdo encriptado. Um atacante não consegue falsificar um fluxo, mas nada na cifra por si só o impede de reorganizar para onde o documento aponta, ou de encaixar objetos de uma revisão anterior do mesmo ficheiro
O token PDF MAC autónomo resolve essa camada. O PDFiumPas deriva-o a partir da chave de encriptação do ficheiro com um /KDFSalt dedicado de 32 bytes registado no dicionário Encrypt, pelo que a posse da palavra-passe é o que permite a um leitor confirmar o token. O resultado é uma única resposta a uma única pergunta: é este 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 ficheiro
pmvsInvalid: Quarantine(Mac.MessageText); // adulterado ou truncado
pmvsUnsupported: RouteForManualReview(Mac.MessageText);
end;
finally
Pdf.Free;
end;
end;
Os quatro valores de estado exigem quatro respostas diferentes, e reduzi-los a um booleano perde a distinção que importa. pmvsNotPresent significa apenas que o ficheiro não tem token, o que descreve quase todos os PDFs encriptados escritos antes de 2024 e não é prova de nada. pmvsInvalid significa que existe um token e não se verifica, o que é uma descoberta genuína e deve interromper o processamento. pmvsUnsupported significa que o token existe numa forma que esta compilação não implementa, o que é uma lacuna de compatibilidade, não um ataque. Tratar "não presente" como "inválido" colocaria de quarentena todo o seu arquivo histórico logo no primeiro dia
O que a encriptação continua a não fazer
As flags de permissão continuam a ser o que sempre foram: um pedido ao software compatível, não um controlo. Os bits /P da Tabela 22 da ISO 32000-1, que proíbem a impressão ou a extração, são respeitados por visualizadores bem comportados e ignorados por tudo o resto, e qualquer pessoa que possua a palavra-passe do utilizador já tem o conteúdo desencriptado. A encriptação é a fronteira; as permissões descrevem a intenção dentro dela
Dois pormenores operacionais valem a pena planear. Primeiro, a encriptação e a modificação posterior interagem: acrescentar uma atualização incremental a um documento encriptado tem regras próprias, abordadas em atualizações incrementais em PDFs encriptados, e um token MAC é uma afirmação ao nível do documento que um anexo descuidado 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 alguma vez se esgote, porque a reutilização de nonce no GCM é catastrófica de uma forma que um retorno ao início silencioso ocultaria
Escolher entre as três revisões na prática
Registe quem abre o ficheiro e depois escolha. Para distribuição interna, onde cada leitor é um visualizador atual sob o seu controlo, a R7 com proteção de integridade é a opção mais forte disponível e não há razão para não a usar. Para documentos que saem da organização, a R6 é a predefinição defensável: está normalizada na ISO 32000-2 em vez de numa especificação técnica sobreposta, e o suporte é amplo. Para arquivos e consumidores legados, a R5 é a única escolha que abre de forma fiável, e deve registar o motivo no mesmo local onde regista o resto da sua política de retenção
Seja qual for a sua escolha, verifique a saída em vez de confiar que a chamada foi bem-sucedida. Reabra o ficheiro encriptado, verifique ValidatePdfMac, e confirme que a versão declarada é a que espera, usando as verificações de conformidade de versão em conformidade exata de versão PDF. Uma lista de verificação mais ampla para documentos não fiáveis encontra-se em auditoria de riscos de segurança em PDF
O PDFiumPas é um componente para Delphi e Lazarus construído em torno do motor PDFium, com a pilha de encriptação PDF 2.0 implementada nativamente em Pascal, pelo que o AES-256, o GCM e o token MAC não precisam de qualquer DLL de criptografia externa. A API de encriptação está documentada na página do componente PDFium para Delphi