Articolo tecnico

Cifratura PDF 2.0 AES-GCM in Delphi: ISO/TS 32003

PDFiumPas scrive la cifratura ISO/TS 32003 tramite SaveAsEncrypted: imposta Revision su erR7 e ogni stringa e stream viene protetto con AES-256 in modalità GCM, il cifrario autenticato che PDF 2.0 ha guadagnato nel 2023. Imposta anche EnableIntegrityProtection e il documento porta anche un token PDF MAC standalone, che ValidatePdfMac controlla sul lato lettura

Queste sono due protezioni diverse che vengono regolarmente confuse. GCM autentica ogni valore cifrato. Il MAC autentica il documento nel suo insieme. Le vuoi entrambe, per ragioni diverse

Cosa aggiunge GCM che CBC non ha mai fornito?

L'autenticazione del ciphertext. AES-256 in modalità CBC, lo schema AESV3 in ISO 32000-2, mantiene il contenuto riservato e non dice nulla su se sia arrivato senza modifiche. CBC è malleabile in modi specifici e ben studiati: un attaccante che può invertire bit nel ciphertext produce cambiamenti prevedibili nel plaintext del blocco successivo, e nulla nel formato se ne accorge

GCM chiude questa lacuna. Ogni valore cifrato porta un tag di autenticazione di 16 byte, serializzato per intero come richiede ISO/TS 32003, e la decifratura fallisce invece di restituire un plaintext alterato quando il tag non corrisponde. In termini PDF, una stringa o uno stream manomessi in un documento AESV4 sono un errore bloccante nel punto di utilizzo, non un valore strano che si propaga nella tua applicazione. L'Encrypt dictionary segna questo con /CFM /AESV4 e V 6 / R 7, accanto a una voce extensions che dichiara /ExtensionLevel 32003 e /ExtensionRevision (:2023)

Tre revisioni, tre ecosistemi

TPdfEncryptionRevision offre erR5, erR6 e erR7, e la scelta è una decisione di compatibilità più che crittografica. R5 è lo schema AES-256 originale pubblicato come estensione di PDF 1.7, con un singolo hash della password SHA-256, e si apre praticamente ovunque negli ultimi quindici anni. R6 è la derivazione chiave rinforzata standardizzata in ISO 32000-2, che usa la costruzione iterativa SHA-256/384/512 dell'algoritmo 2.B, ed è ciò che si aspetta un workflow PDF 2.0 o PDF/A-4 attuale. R7 è ISO/TS 32003, che usa la stessa derivazione 2.B con AES-GCM come cifrario

Il supporto dei reader segue esattamente quest'ordine, e il supporto a R7 è ancora scarso fuori dai viewer mainstream attuali. È lo stesso compromesso che governa qualsiasi funzionalità PDF 2.0: l'opzione più nuova è la migliore ingegneria e il pubblico più ristretto. Decidi in base a chi deve aprire il file, e se la risposta è «un sistema di records nessuno ha aggiornato dal 2019», la risposta è R5, indipendentemente da cosa preferisca la security policy

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 standalone

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

Perché un MAC di documento sopra un cifrario autenticato?

Perché i tag GCM proteggono i valori, non la disposizione dei valori. Ogni stringa e stream in un documento AESV4 è autenticato individualmente, eppure la cross-reference table, la numerazione degli oggetti e il trailer sono struttura, non contenuto cifrato. Un attaccante non può falsificare uno stream, ma nulla nel solo cifrario gli impedisce di riorganizzare a quali oggetti punta il documento, o di innestare oggetti da una revisione precedente dello stesso file

Il token PDF MAC standalone affronta quel livello. PDFiumPas lo deriva dalla chiave di cifratura del file con un /KDFSalt dedicato di 32 byte registrato nell'Encrypt dictionary, così è il possesso della password a permettere a un reader di confermare il token. Il risultato è un'unica risposta a un'unica domanda: questo documento, nel suo insieme, è il documento che è stato scritto

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);       // nessun token in questo file
      pmvsInvalid:     Quarantine(Mac.MessageText);   // manomesso o troncato
      pmvsUnsupported: RouteForManualReview(Mac.MessageText);
    end;
  finally
    Pdf.Free;
  end;
end;

I quattro valori di stato richiedono quattro risposte diverse, e comprimerli in un booleano perde la distinzione che conta. pmvsNotPresent significa che il file semplicemente non ha token, il che descrive quasi ogni PDF cifrato scritto prima del 2024 e non è prova di nulla. pmvsInvalid significa che un token è presente e non verifica, il che è un riscontro genuino e dovrebbe fermare l'elaborazione. pmvsUnsupported significa che il token esiste in una forma che questa build non implementa, il che è una lacuna di compatibilità, non un attacco. Trattare «non presente» come «non valido» metterebbe in quarantena l'intero catalogo storico il primo giorno

Cosa la cifratura ancora non fa

I flag di permesso restano ciò che sono sempre stati: una richiesta rivolta a software conforme, non un controllo. I bit /P della Table 22 di ISO 32000-1 che vietano stampa o estrazione sono rispettati dai viewer ben educati e ignorati da tutto il resto, e chiunque possieda la user password possiede già il contenuto decifrato. La cifratura è il confine; i permessi descrivono l'intento al suo interno

Due dettagli operativi vale la pena pianificare. Primo, cifratura e modifica successiva interagiscono: aggiungere un incremental update a un documento cifrato ha regole proprie, trattate in incremental update su PDF cifrati, e un token MAC è una dichiarazione a livello di documento che un append incauto invaliderà. Secondo, la costruzione GCM usa un contatore IV deterministico, e PDFiumPas solleva un'eccezione invece di riutilizzare un valore di contatore se quello spazio si esaurisse mai, perché il riutilizzo di un nonce in GCM è catastrofico in un modo che un wraparound silenzioso nasconderebbe

Scegliere tra le tre revisioni in pratica

Scrivi chi apre il file, poi scegli. Per la distribuzione interna dove ogni reader è un viewer attuale sotto il tuo controllo, R7 con integrity protection è l'opzione più forte disponibile e non c'è motivo per non usarla. Per i documenti che lasciano l'organizzazione, R6 è il default difendibile: è standardizzato in ISO 32000-2 anziché in una specifica tecnica sopra di esso, e il supporto è ampio. Per archivi e consumer legacy, R5 è l'unica scelta che si apre in modo affidabile, e dovresti registrare il perché nello stesso posto in cui registri il resto della tua retention policy

Qualunque tu scelga, verifica l'output invece di fidarti che la chiamata sia riuscita. Riapri il file cifrato, controlla ValidatePdfMac, e conferma che la versione dichiarata sia quella attesa, usando i controlli di conformità versione in conformità esatta della versione PDF. Una checklist di ingestion più ampia per documenti non attendibili è in audit dei rischi di sicurezza PDF

PDFiumPas è un componente Delphi e Lazarus attorno al motore PDFium con lo stack di cifratura PDF 2.0 implementato nativamente in Pascal, così AES-256, GCM e il token MAC non richiedono alcuna DLL crittografica esterna. L'API di cifratura è documentata sulla pagina del componente Delphi PDFium