Salta ai contenuti

Verifica della firma: lato verifica crittografica AdES / PAdES

NextPDF Enterprise verifica crittograficamente le firme digitali. Il lato verifica legge dal PDF un CMS SignedData o un token timestamp RFC 3161, ricalcola i digest, verifica le firme, vincola ogni firma al proprio certificato di firma e convalida la catena di certificati — inclusa l’elaborazione delle policy di certificato — rispetto a uno store di trust anchor fornito dal chiamante. Questa pagina descrive il comportamento: specifica cosa viene verificato, cosa viene rifiutato in modalità fail-closed, quali algoritmi sono supportati e dove si colloca il confine di fiducia.

Questo è distinto da Validation, che esegue controlli di policy strutturali in sola lettura e deliberatamente non effettua alcuna operazione crittografica. È inoltre la controparte lato verifica del produttore di firme, che scrive strutture PAdES B-LT / B-LTA.

Terminal window
composer require nextpdf/enterprise:^3

La verifica è basata sulle evidenze e opera in modalità fail-closed: un controllo che non può essere confermato in modo positivo non produce un esito positivo. Gli elementi seguenti concorrono a un unico esito rappresentato da un ValidationReport.

Verifica crittografica di CMS / token timestamp. Uno stack DER autonomo, rigoroso e a lunghezza definita esegue il parsing del CMS SignedData e del token timestamp RFC 3161. Un token viene accettato solo quando contiene esattamente un SignerInfo, i suoi attributi firmati superano un parsing rigoroso, il certificato del firmatario viene risolto, l’attributo message-digest corrisponde al digest ricalcolato, il vincolo obbligatorio al certificato di firma (ESS signing-certificate-v2) è valido e la firma SignerInfo si verifica sugli attributi firmati ri-tagged. La regola di corrispondenza del digest segue il modello di verifica RFC 5652 §5.6 / §5.4: il destinatario ricalcola il message digest del contenuto e la firma è valida solo quando tale valore è uguale all’attributo firmato messageDigest — un verificatore non si fida mai di un digest fornito dal produttore.

Convalida del certificato TSA al genTime. Il genTime del timestamp è l’istante UTC in cui il token è stato creato (RFC 3161 §2.4.2). Il certificato di firma TSA viene convalidato in quell’istante, non al «momento attuale»: il suo extended key usage deve essere un singolo id-kp-timeStamping critico (RFC 3161 §2.3), e la finestra di validità, la catena, la provenienza del trust anchor e la revoca vengono valutate rispetto al genTime. Una catena ben formata dal punto di vista strutturale ma che non raggiunge un trust anchor configurato non può mai supportare un esito positivo.

Firme di documento basic PAdES detached. Un extractor concreto esegue una verifica basic AdES / PAdES effettiva per una firma di documento detached: il message digest viene ricalcolato sull’intervallo di byte firmato e confrontato, la firma viene verificata e il vincolo al certificato di firma è obbligatorio. Questo sostituisce il precedente fallback solo strutturale. Il verificatore di timestamp e l’extractor della firma di documento condividono un unico validator ESS issuer-and-serial, così non possono divergere nel parsing del vincolo al certificato.

Catena di copertura DocTimeStamp d’archivio. validateArchivalTimestampChain() convalida una catena di token DocTimeStamp attendibili sugli intervalli di byte del PDF come evidenza d’archivio B-LTA. L’imprint di ogni token è vincolato ai byte effettivi del ByteRange che copre, la catena rispetta il rigoroso ordinamento ETSI, la catena TSA di ogni token è ancorata alla fiducia e la catena deve coprire il file fino al suo marker di fine file. Raggiunge un esito completamente positivo solo per una catena completa, ancorata alla fiducia e che copre fino all’EOF.

Elaborazione delle policy di certificato (RFC 5280 §6.1.4). La convalida del path applica l’elaborazione completa delle policy di certificato: un policy tree strutturato a nodi, il policy mapping con fallback anyPolicy e il folding di policyConstraints / inhibitAnyPolicy, con il supporto di un reader DER fail-closed per le policy-extension. Le variabili di stato dell’elaborazione del path explicit_policy e inhibit_anyPolicy (RFC 5280 §6.1.2) determinano se è richiesto un valid-policy tree non vuoto; la fase di wrap-up interseca il valid-policy tree con lo user-initial-policy-set (RFC 5280 §6.1.4). In assenza di policy richieste e con anyPolicy accettato, l’elaborazione non è vincolata: è l’impostazione predefinita, invariata rispetto al comportamento precedente.

Il lato verifica accetta il seguente set di algoritmi e fallisce in chiusura su qualsiasi elemento esterno a esso: un algoritmo non supportato produce una verifica rifiutata, mai un superamento silenzioso.

FamigliaSupportatoNote
RSA (PKCS#1 v1.5)rsaEncryption con SHA-2 e gli sha*WithRSAEncryption OIDAccettato
ECDSAcurve P-256, P-384, P-521Accettato
RSASSA-PSSNon supportato → fail-closed
EdDSANon supportato → fail-closed
digest SHA-3Non supportato → fail-closed
SHA-1Debole: una firma basic che si verifica con SHA-1 viene degradata a un fallimento dei vincoli crittografici, non a un esito positivo

Il lato verifica si utilizza tramite il motore pubblico e i contratti Core / Pki. Le classi di strategia concrete sono interne.

TipoGenereRuolo
AdESValidationEngineclasseIl punto di ingresso lato verifica: convalida della firma e della catena d’archivio.
AdESValidationEngine::validateArchivalTimestampChain()metodoConvalida una catena di copertura DocTimeStamp attendibile sugli intervalli di byte del PDF.
ValidationReportrisultatoL’esito strutturato: lo stato complessivo più i finding per ciascun controllo.
PathValidatorInterfaceinterfaccia (NextPDF\…\Pki)L’SPI di convalida del certification path da cui dipende il motore.
PathValidationOptionsvalue objectControlli dell’elaborazione delle policy: requireExplicitPolicy, inhibitAnyPolicy, inhibitPolicyMapping, maxPolicyFanout.
TrustAnchorStoreInterfaceinterfacciaL’insieme di anchor attendibili fornito dal chiamante rispetto al quale viene valutata la catena.

Il metodo della catena d’archivio ha questa firma:

public function validateArchivalTimestampChain(
string $pdfBytes,
array $dssData = [],
?TrustAnchorStoreInterface $anchors = null,
): ValidationReport;

Raggiunge un esito completamente positivo solo quando la catena DocTimeStamp è interamente verificata, ancorata alla fiducia e copre il file fino al suo marker EOF.

CertificateChainValidator::validate() accetta un set di policy iniziali (lo user-initial-policy-set di RFC 5280). Il valore predefinito è anyPolicy — non vincolato — quindi una catena ordinaria non viene influenzata; passare un set esplicito oppure impostare requireExplicitPolicy per esigere un valid-policy tree non vuoto.

use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;
$report = $engine->validateArchivalTimestampChain($pdfBytes, [], $trustAnchors);
if ($report->isTotalPassed()) {
// A complete, trust-anchored, EOF-covering DocTimeStamp chain.
}
use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;
use Psr\Log\LoggerInterface;
final readonly class ArchivalEvidenceCheck
{
public function __construct(
private AdESValidationEngine $engine,
private LoggerInterface $logger,
) {}
public function check(string $pdfBytes, TrustAnchorStoreInterface $anchors): bool
{
$report = $this->engine->validateArchivalTimestampChain($pdfBytes, [], $anchors);
foreach ($report->findings as $finding) {
$this->logger->info('archival.finding', [
'check' => $finding->checkId,
'status' => $finding->status->value,
]);
}
// A positive result proves byte-range coverage by a trusted timestamp
// chain — it is one input to your decision, not a legal conclusion.
return $report->isTotalPassed();
}
}

Modifiche di comportamento e note di aggiornamento

Sezione intitolata “Modifiche di comportamento e note di aggiornamento”

Il lato verifica è passato dall’accettazione strutturale / temporale alla verifica crittografica completa. Chi faceva affidamento sul comportamento precedente, più permissivo, dovrebbe esaminare queste modifiche.

  • Fail-closed su un timestamp riconoscibile ma non verificabile. Un DocTimeStamp o un token d’archivio che in precedenza superava la verifica in base a controlli strutturali e temporali ora richiede una verifica crittografica completa — firma, message-digest e vincolo al certificato di firma. Un token che non si verifica non produce più una prova positiva di esistenza; viene mappato su un esito indeterminato o fallito.
  • Le firme basic con SHA-1 vengono degradate, non superate. Una firma di documento basic che si verifica ma utilizza SHA-1 viene segnalata come fallimento dei vincoli crittografici, non come esito completamente positivo.
  • L’elaborazione delle policy di certificato RFC 5280 §6.1.4 è applicata. Una catena il cui explicit_policy raggiunge zero con un valid-policy tree vuoto ora fallisce — anche quando la causa è un policyConstraints interno alla catena con requireExplicitPolicy. Le catene predefinite e non vincolate (nessuna policy richiesta, anyPolicy accettato) non ne sono influenzate.
  • Modifica della firma del costruttore (BC break). AdESValidationEngine::__construct() ora tipizza il parametro $chainValidator come SPI Pki\PathValidatorInterface, con impostazione predefinita lazy a Pki\CertificateChainValidator::withDefaults(). In precedenza era il concreto Ltv\CertificateChainValidator. Un chiamante che iniettava il validator LTV concreto deve invece iniettare l’implementazione dell’SPI Pki. Il validator Pki incapsula lo stesso motore di path strutturale e aggiunge l’elaborazione dei name-constraint e delle policy; per gli input predefiniti conformi è un no-op.
  • Algoritmo non supportato ≠ inconcludente. RSASSA-PSS, EdDSA e SHA-3 vengono rifiutati fail-closed, non considerati inconcludenti. Se i firmatari li utilizzano, questo lato verifica non restituirà un risultato positivo per essi.
  • La fiducia è relativa agli anchor. La verifica è sempre relativa allo store di trust anchor fornito. Un insieme di anchor vuoto o errato produce un esito non attendibile indipendentemente dalla correttezza crittografica.
  • genTime, non il momento attuale. Il certificato TSA viene giudicato al genTime del token. Un certificato TSA nel frattempo scaduto può comunque supportare un token creato mentre era valido; un certificato non ancora valido al genTime non può.
  • Copertura fino all’EOF. La catena d’archivio deve coprire il documento fino al suo marker EOF. Un timestamp che copre solo un prefisso del file non stabilisce la copertura dell’intero documento.
  • Non-revoca non comprovata ≠ Good. Un verdetto Valid richiede uno stato di non-revoca conclusivo. Se sia OCSP sia CRL restituiscono Unknown o Unavailable, anche una firma crittograficamente solida, con catena valida e ancorata alla fiducia, si risolve in Indeterminate — fornire materiale Good OCSP/CRL incorporato per il certificato del firmatario affinché raggiunga Valid.

La verifica avviene in-process sui byte PDF forniti e sul materiale di convalida incorporato; il costo cresce con la lunghezza della catena e il numero di timestamp. Durante la verifica non viene effettuato alcun round trip di rete — il materiale di revoca e di fiducia deriva da ciò che il chiamante fornisce o da ciò che è incorporato nel documento. La verifica è deterministica: gli stessi input e gli stessi trust anchor producono lo stesso report.

  • Fail-closed è l’impostazione predefinita. Ogni fase di accettazione rifiuta materiale che non può verificare in modo positivo. Ciò impedisce a un documento di dichiarare una validità che il motore non ha mai stabilito.
  • L’append-after-timestamp viene neutralizzato dalla copertura fino all’EOF. Poiché l’imprint di ogni timestamp d’archivio è vincolato ai byte effettivi del ByteRange e la catena deve raggiungere l’EOF, il contenuto aggiunto dopo un timestamp non è coperto da esso e non ne acquisisce il peso probatorio.
  • Trattare l’input come ostile. I byte PDF, il CMS incorporato e i token timestamp provenienti da fonti non attendibili vengono analizzati da un reader DER rigoroso a lunghezza definita che rifiuta le codifiche malformate o a lunghezza indefinita.

La verifica è in-process e locale, senza I/O di rete. I certificati e le firme contengono l’identità del soggetto; applicare i propri controlli di conservazione e minimizzazione ai report e a qualsiasi dato di certificato estratto.

I finding contengono identificatori dei controlli e stati. Alcune diagnostiche possono riportare i subject name dei certificati o i numeri di serie; eseguire lo scrubbing o l’oscuramento di tali campi prima di inoltrare i log a sink condivisi.

Dichiarare questi confini nell’output rivolto all’utente affinché un risultato positivo non venga sovrainterpretato.

  • validateArchivalTimestampChain() dimostra la copertura degli intervalli di byte, non la raggiungibilità tramite xref. Stabilisce che una catena di timestamp attendibile copre crittograficamente gli intervalli di byte del documento fino all’EOF. Non esegue analisi di raggiungibilità degli oggetti a livello di xref o di startxref; questo è fuori ambito per progettazione. Gli attacchi append-after-timestamp vengono neutralizzati dalla regola di copertura fino all’EOF insieme all’ancoraggio alla fiducia, non dall’analisi del grafo degli oggetti.
  • Fuori ambito per progettazione. Gli Evidence Record (RFC 4998 / RFC 6283); la verifica dei token timestamp RSASSA-PSS, EdDSA o SHA-3; l’integrazione con trusted-list (TSL) e TSA qualificate; e il recupero online della revoca della TSA non sono forniti da questo lato verifica. La revoca viene valutata a partire dal materiale già disponibile al verificatore.
ComportamentoRiferimentoStato
Valore della firma / token timestamp memorizzati con codifica DER in /ContentsISO 32000-2 §12.8.1Sottoposto a parsing e verificato
Dizionario del document timestampISO 32000-2 §12.8.5Letto per la catena d’archivio
Il destinatario ricalcola il digest del contenuto; deve essere uguale all’attributo messageDigestRFC 5652 §5.6 / §5.4Applicato
Il certificato TSA reca un unico EKU id-kp-timeStamping criticoRFC 3161 §2.3Verificato al genTime
genTime è l’istante di creazione UTCRFC 3161 §2.4.2Utilizzato come istante di convalida
Variabili di stato dell’elaborazione delle policy (explicit_policy, inhibit_anyPolicy)RFC 5280 §6.1.2Elaborato
Il wrap-up interseca il valid-policy tree con lo user-initial-policy-setRFC 5280 §6.1.4Applicato
Voci DSS e document time-stamp per le firme a lungo termineETSI EN 319 142-2 §5.5Convalidato come evidenza d’archivio

Tutte le clausole sono parafrasate. NextPDF non riproduce il testo normativo; consultare gli standard pubblicati per la formulazione autorevole. NextPDF non avanza alcuna pretesa di certificazione AdES / PAdES. Il lato verifica implementa i controlli crittografici descritti dalle specifiche citate; non è un servizio di convalida certificato e non produce alcuna attestazione di terze parti.

Quando il profilo FIPS Enterprise è attivo, il vincolo si applica agli algoritmi di digest e di firma accettati dal verificatore. La logica di verifica — ricalcolo del digest, controlli della firma, vincolo al certificato e convalida del path — resta invariata.

AssetAvversarioRischioMitigazione
Token timestampToken contraffatto o alteratoUna falsa prova di esistenzaVerifica crittografica completa; fail-closed su qualsiasi elemento non verificabile
Certificato TSAIssuer non attendibileFiducia apparente che il verificatore non dovrebbe affermareCatena convalidata fino a un anchor fornito dal chiamante al genTime; una catena non attendibile non supera mai la verifica
Byte del documentoAppend-after-timestampIl contenuto acquisisce il peso di un timestamp senza coperturaImprint vincolato ai byte effettivi del ByteRange + regola di copertura fino all’EOF
Algoritmo deboleDowngrade a SHA-1 / schema non supportatoUna firma debole interpretata come validaSHA-1 degradato; RSASSA-PSS / EdDSA / SHA-3 fail-closed

Questo lato verifica è una funzionalità Enterprise e viene distribuito nel pacchetto nextpdf/enterprise. NextPDF Core rileva la presenza di una firma e produce firme B-B / B-T; non fornisce questo lato verifica crittografica. Ottenere una licenza.

Il lato verifica è subordinato all’edizione Enterprise (license_feature_flag: enterprise). Viene risolto attraverso i contratti Core e Pki; l’API pubblica non cambia con un aggiornamento di edizione.

  • Un token CMS o timestamp viene accettato solo con esattamente un SignerInfo, attributi firmati sottoposti a parsing rigoroso, un certificato del firmatario risolto, un message-digest corrispondente, il vincolo obbligatorio al certificato di firma e una firma SignerInfo che si verifica.
  • Il certificato TSA viene convalidato al genTime del token: un unico EKU id-kp-timeStamping critico, finestra di validità, catena ancorata alla fiducia e revoca.
  • Un verdetto Valid richiede inoltre uno stato di non-revoca conclusivo — almeno un Good autorevole (una risposta OCSP verificata come good, oppure una CRL aggiornata che colloca il serial al di fuori di una lista non scaduta). Uno stato che dimostra soltanto la revoca non comprovata, in cui sia OCSP sia CRL sono Unknown o Unavailable, si risolve in Indeterminate, mai Valid (ETSI EN 319 102-1: revocation status-unavailable → INDETERMINATE). Poiché il percorso di fallback su CRL attesta solo la freschezza della lista e non la revoca per singolo serial, una catena basata solo su CRL senza un OCSP Good è comunemente Indeterminate.
  • validateArchivalTimestampChain() raggiunge un esito completamente superato solo per una catena DocTimeStamp completa, ancorata alla fiducia e che copre fino all’EOF; dimostra la copertura degli intervalli di byte, non la raggiungibilità tramite xref.
  • L’elaborazione delle policy di certificato segue RFC 5280 §6.1.4; le catene predefinite non vincolate non ne sono influenzate.
  • Gli algoritmi supportati sono RSA (PKCS#1 v1.5 con SHA-2) ed ECDSA (P-256/384/521); RSASSA-PSS, EdDSA e SHA-3 falliscono in chiusura; SHA-1 viene degradato.

Questa pagina pubblica descrive solo il comportamento lato verifica osservabile dall’esterno. Menziona il motore pubblico, i contratti Pki / trust-anchor e il metodo validateArchivalTimestampChain() attraverso la superficie supportata. Gli interni concreti di DER, CMS, policy-processor e path-validator si trovano nel deep reference riservato sotto NDA.

NextPDF Core rileva la presenza di una firma e produce firme B-B / B-T, ma non verifica crittograficamente i token CMS o timestamp, non convalida una catena d’archivio e non esegue l’elaborazione delle policy RFC 5280 §6.1.4. Un deployment solo Core non dispone di un lato verifica equivalente; vedere Security / Signing (Core).

NextPDF Pro aggiunge strategie di firma e gestione delle fatture elettroniche, ma non fornisce questo lato verifica crittografica; la convalida della catena d’archivio e l’elaborazione delle policy di certificato sono distribuite solo in nextpdf/enterprise.

Il lato verifica è descritto a livello di comportamento. Lo stack DER rigoroso, il parser CMS, il policy processor e gli interni del path-validator sono fuori ambito per la superficie pubblica e non vengono riprodotti qui.

La verifica dipende dallo store di trust anchor e da qualsiasi materiale di revoca fornito dal chiamante o incorporato nel documento. NextPDF Enterprise valuta tale materiale; non gestisce una trust list, una TSA o un servizio di revoca. L’operatore è responsabile della selezione degli anchor e della freschezza del materiale di revoca incorporato.

Questa pagina è contrassegnata come export_control_class: legal-review-required; riguarda la verifica crittografica. È richiesta l’approvazione legale prima che venga impostato il flag publish. Un risultato di verifica positivo è una dichiarazione crittografica sulle firme e sui timestamp del documento — non è un parere legale, una determinazione di qualificazione eIDAS o una certificazione. NextPDF non avanza alcuna pretesa di certificazione AdES / PAdES. Consultare i propri consulenti legali e di conformità per i propri obblighi normativi.