Per far sì che un PDF firmato si convalidi a distanza di anni, dopo la scadenza del certificato di firma e la rotazione della sua CA, il componente PDFium può produrre firme PAdES a lungo termine su Windows: una marca temporale RFC 3161 per un'ora attendibile, un Document Security Store che incorpora il materiale di convalida e una marca temporale di archivio DocTimeStamp sull'intero file. Queste tre aggiunte rappresentano i livelli di baseline PAdES B-T, B-LT e B-LTA, e il componente PDFium li raggiunge tutti con una singola chiamata di firma. Questa funzionalità è disponibile solo su Windows, controllata da PadesCryptoAvailable
Questo articolo è il terzo di una serie. Il primo, firmare PDF con PAdES B-B usando PDFium VCL, tratta la firma di base; il secondo, ispezionare le firme digitali PDF e i livelli PAdES, copre la lettura della firma e l'identificazione del livello raggiunto. Qui l'attenzione si concentra sull'archiviazione: firme che devono sopravvivere alla scadenza dei certificati e rimanere verificabili per un periodo di conservazione misurato in anni, non in settimane
Perché una firma PDF valida smette di convalidarsi nel tempo?
Una firma di base risponde a una sola domanda: se questi byte sono stati modificati dopo la firma. Di per sé non dimostra quando sia avvenuta la firma, ed è questa lacuna a comprometterne la verifica in seguito. La struttura CMS contiene un attributo relativo all'ora della firma, ma il firmatario scrive quel valore in base al proprio orologio, pertanto un convalidatore non ha motivo di ritenerlo attendibile. Quando il certificato di firma scade o la CA lo revoca, un convalidatore rigoroso non può più distinguere una firma apposta mentre il certificato era valido da una contraffatta dopo la sua scadenza. La firma era corretta il giorno in cui è stata creata e diventa non verificabile senza alcuna colpa da parte sua
L'archiviazione a lungo termine risolve questo problema in due mosse. In primo luogo, una terza parte attendibile, una Time Stamping Authority, attesta l'ora crittograficamente in modo da non dipendere dall'onestà del firmatario. In secondo luogo, ogni certificato, risposta di revoca e CRL necessari per compilare e verificare la catena di attendibilità vengono incorporati all'interno del PDF stesso, in modo che la convalida non dipenda da server che potrebbero non essere più attivi al momento del controllo. PAdES, standardizzato come ETSI EN 319 142-1, organizza questi elementi in livelli di baseline, e il componente PDFium scrive le strutture richieste da ciascun livello
Cos'è una firma PDF LTV o con marca temporale di archivio?
PAdES definisce quattro livelli di baseline che si basano l'uno sull'altro, e il componente PDFium li espone tramite l'enumerazione TPadesLevel (plB_B, plB_T, plB_LT, plB_LTA). B-B è la firma semplice. B-T aggiunge una marca temporale attendibile sul valore della firma. B-LT (a lungo termine) aggiunge il materiale di convalida incorporato, la proprietà comunemente indicata come "LTV". B-LTA (a lungo termine con marca temporale di archivio) avvolge il tutto in un'ulteriore marca temporale che copre l'intero file, in modo che il materiale incorporato sia dimostrabilmente integro dal momento dell'archiviazione
La lettura pratica è a gradini. B-T dimostra quando. B-LT dimostra con cosa la firma può essere ancora verificata. B-LTA dimostra che l'intero pacchetto non è stato manomesso da quando è stato sigillato, ed è il livello che viene rinnovato, aggiungendo una nuova DocTimeStamp prima della scadenza di quella precedente, per estendere l'archivio a tempo indeterminato. Per un contratto o un documento di conformità con un obbligo di conservazione prolungato, il target è B-LTA; B-LT è la soglia pragmatica
Aggiungere un'ora attendibile: PAdES B-T con RFC 3161
Il componente PDFium trasforma una firma B-B in B-T impostando due campi su TPadesSignOptions: elevare Level a plB_T e fornire un TsaUrl. Quando sono presenti entrambi, la pipeline di firma esegue l'hash degli ottetti della firma grezza con SHA-256, pacchettizza tale digest come messageImprint RFC 3161, invia la richiesta tramite POST alla TSA su WinHttp e incorpora il token restituito come attributo non firmato signature-time-stamp (OID 1.2.840.113549.1.9.16.2.14) in unsignedAttrs [1] di SignerInfo, secondo EN 319 142-1 §6.3. La marca temporale copre specificamente il valore della firma, legando l'ora attendibile a quella firma esatta
uses
PDFium, FPdfPades;
procedure SignWithTimestamp;
var
Pdf: TPdf;
Options: TPadesSignOptions;
begin
Pdf := TPdf.Create(nil);
try
if not Pdf.PadesCryptoAvailable then
raise Exception.Create('PAdES signing backend is Windows-only');
Pdf.FileName := 'contract.pdf';
Pdf.Active := True;
Options := TPadesSignOptions.Default;
Options.CertificateThumbprint := 'A1B2C3D4E5F6071829304152637485960A1B2C3D';
Options.Level := plB_T;
Options.TsaUrl := 'http://timestamp.example-tsa.com/tsr';
Options.Reason := 'Contract execution';
// Nonce impostato su 0: il componente ricava un valore anti-replay univoco.
Pdf.SignPades('contract-bt.pdf', Options);
finally
Pdf.Free;
end;
end;
Il valore CertificateThumbprint è l'hash SHA-1, in formato esadecimale, di un certificato presente nell'archivio "MY" dell'utente corrente la cui chiave privata può essere utilizzata. Il campo Nonce è il valore anti-replay RFC 3161; lasciandolo a zero, il componente ne ricava uno univoco per richiesta da un fold SHA-256 di un contatore, dell'orologio, del conteggio dei tick e dell'ID del processo, in modo che due richieste inviate nello stesso millisecondo non entrino in collisione. Passa un tuo valore solo se disponi di un RNG crittografico di cui preferisci fidarti. Un avvertimento onesto: il livello B-T richiede una TSA raggiungibile, pertanto la firma comporta ora una chiamata di rete ereditando la disponibilità e la latenza della TSA
Incorporare il materiale di convalida: B-LT e B-LTA in un'unica chiamata
Il passaggio alla convalida a lungo termine è un'unica modifica: impostare Level su plB_LTA e mantenere il TsaUrl. Il componente PDFium esegue quindi l'intero percorso all'interno di un'unica chiamata SignPades. Firma in formato B-B, applica la marca temporale per B-T, inserisce il Document Security Store per B-LT e appone la marca temporale di archivio per B-LTA, ciascuno come proprio aggiornamento incrementale in modo che i byte precedenti rimangano del tutto integri
procedure SignForArchive;
var
Pdf: TPdf;
Options: TPadesSignOptions;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'contract.pdf';
Pdf.Active := True;
Options := TPadesSignOptions.Default;
Options.CertificateThumbprint := 'A1B2C3D4E5F6071829304152637485960A1B2C3D';
Options.Level := plB_LTA; // gestisce il percorso B-B -> B-T -> B-LT -> B-LTA
Options.TsaUrl := 'http://timestamp.example-tsa.com/tsr';
Options.Location := 'Head Office';
// Una singola chiamata scrive la marca temporale, il DSS e la DocTimeStamp di archivio.
Pdf.SignPades('contract-lta.pdf', Options);
finally
Pdf.Free;
end;
end;
Per il livello B-LT, il componente PDFium compila la catena di certificati con CertGetCertificateChain e scrive un dizionario /DSS contenente il certificato del firmatario e ogni CA intermedia in un array /Certs (con array paralleli /OCSPs e /CRLs), insieme a un indicatore /Extensions /ESIC di Livello 1, esattamente come prescritto da EN 319 142-1 §5.4.2. La radice autofirmata è deliberatamente omessa, poiché la specifica RFC 5652 §10.2.3 lo consente e la radice è già un'ancora di attendibilità in possesso del convalidatore. Il risultato è una firma che un lettore può verificare disponendo unicamente del file
Per il livello B-LTA il componente aggiunge un Document Time-stamp: un dizionario delle firme con /SubFilter /ETSI.RFC3161 il cui /ByteRange copre l'intero file, con /Contents che ospita un token RFC 3161 su quell'intervallo, promuovendo l'indicatore ESIC a Livello 2. Questo rappresenta la fase di archiviazione descritta in §5.4.3 e TS 119 142-3. Poiché la DocTimeStamp copre sia il DSS sia la firma, dimostra che il materiale di convalida incorporato era presente e inalterato al momento dell'archiviazione, ossia esattamente ciò che un obbligo di conservazione prolungato deve poter dimostrare
Integrare una firma già esistente
A volte la firma è già presente sul documento ed è solo necessario aggiungere o aggiornare l'archivio di convalida, ad esempio per portare una firma B-B di terze parti a livello B-LT per il proprio archivio. Il componente PDFium espone l'iniettore DSS direttamente tramite SaveAsPadesDss, che aggiunge le strutture /DSS e /Extensions como aggiornamento incrementale senza modificare i byte della firma esistente
procedure AddValidationStore;
var
Pdf: TPdf;
DssOpts: TPadesDssOptions;
Cert: TPadesDssMaterial;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'already-signed.pdf';
Pdf.Active := True;
DssOpts := TPadesDssOptions.Default;
DssOpts.EsicExtensionLevel := 1; // 1 per B-LT, 2 per B-LTA
Cert.DerBytes := LoadSignerCertDer; // il tuo certificato con codifica DER
SetLength(DssOpts.Certs, 1);
DssOpts.Certs[0] := Cert;
Pdf.SaveAsPadesDss('already-signed-lt.pdf', DssOpts);
finally
Pdf.Free;
end;
end;
Fornisci i certificati con codifica DER e, opzionalmente, le risposte OCSP e le CRL di cui un convalidatore avrà bisogno. Imposta EsicExtensionLevel su 1 per un archivio B-LT o su 2 quando seguirà una DocTimeStamp. Lascia IncludeVri al valore predefinito False: la specifica EN 319 142-1 §5.4.2.3 considera opzionale il dizionario /VRI per singola firma e ne sconsiglia l'uso a meno che un visualizzatore specifico di destinazione non lo richieda
Costi e limiti da pianificare
Tre limiti intrinseci definiscono l'uso di questi livelli. In primo luogo, il backend crittografico è disponibile solo su Windows: la firma e la marcatura temporale passano attraverso i componenti CNG e WinHttp della piattaforma, quindi PadesCryptoAvailable restituisce False altrove e SignPades solleva un'eccedenza. L'ispezione in lettura trattata nell'articolo di accompagnamento rimane multipiattaforma; solo la scrittura delle firme è vincolata a Windows. In secondo luogo, i livelli B-T e B-LTA dipendono da una Time Stamping Authority, il che comporta un viaggio di rete al momento della firma e l'integrazione di un servizio esterno, con i relativi tempi di attività e limiti di frequenza, nel percorso di firma
In terzo luogo, ciascun livello comporta un costo in termini di archiviazione. Ogni fase aggiunge un aggiornamento incrementale anziché riscrivere il file, il DSS incorpora una catena di certificati completa e la DocTimeStamp di archivio riserva spazio per il proprio token, pertanto un file B-LTA è significativamente più grande dell'originale B-B. Si tratta di un compromesso intenzionale: consumi byte ora per assicurarti la verificabilità futura. Per la maggior parte degli archivi di contratti e conformità è il compromesso ideale, ma vale la pena effettuare misurazioni sui propri documenti invece di fare supposizioni. Quando hai bisogno di confermare che un file finito abbia effettivamente raggiunto il livello pianificato, verificalo con le tecniche descritte in ispezionare le firme digitali PDF e i livelli PAdES, e se stai rafforzando una pipeline di documenti in modo più ampio, le note sull'auditing dei rischi di sicurezza dei PDF coprono i relativi controlli di accompagnamento
Le funzionalità di firma PAdES, DSS e marca temporale di archivio mostrate qui fanno parte di PDFium Component per Delphi e C++Builder, la cui pagina prodotto contiene il riferimento completo alla firma e i requisiti di piattaforma