Salta ai contenuti
getnextpdf.com

Enterprise edizione

Verifica delle firme — Riferimento approfondito

Questa pagina è il riferimento approfondito della superficie di verifica AdES in NextPDF Enterprise. Il punto di ingresso è NextPDF\Enterprise\Security\Validation\AdESValidationEngine. Implementa i flussi di validazione modellati secondo ETSI di NextPDF per i controlli basic, con tempo, a lungo termine e con marca temporale di archiviazione: validazione basic, validazione con tempo, validazione con dati a lungo termine e validazione della catena di copertura DocTimeStamp di archiviazione. Gli esiti sono valori ValidationReport che trasportano casi enum MainIndication e SubIndication con valori stringa URN ETSI. Superfici di supporto documentate qui: la SPI SignatureDataExtractor e la sua implementazione CmsSignatureDataExtractor, lo scanner a livello di byte PdfSignatureDictionaryScanner, la superficie di validazione del percorso NextPDF\Enterprise\Security\Pki e BatchSignatureValidator. Per una guida a livello di flusso di lavoro, vedere Verifica delle firme: verifica crittografica AdES / PAdES.

Questa capacità è inclusa in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di livello Enterprise. Un deployment privo di tale titolo non carica le classi della capacità. Confronta le edizioni e ottieni una licenza.

SimboloParametriComportamento predefinitoRestituisceSolleva o fallisce conNote
AdESValidationEngine::__construct11 parametri opzionali: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy e cinque collaboratori verifier opzionaliTutti i valori predefiniti sono fail-closed: validatore di percorso Pki sull’orologio del motore, nessun extractor, nessuno store di fiducia TSANuovo motoreNon sollevaSenza store di fiducia, la valutazione della catena TSA riporta non attendibile; ciò mappa a INDETERMINATE, mai a un esito positivo
AdESValidationEngine::validateBasicstring $signedData, string $signatureValidazione basic: formato, digest, crypto, algoritmo debole, catena, revoca vincolata alla provenienzaValidationReportNon solleva; i fallimenti di estrazione e di percorso mappano a report fail-closedSenza un extractor, solo controlli di guardia; vedere i casi limite
AdESValidationEngine::validateWithTimestring $signedData, string $signature, DateTimeImmutable $claimedTimePrima la validazione basic; finestra del certificato e revoca confrontate con il tempo dichiaratoValidationReportNon sollevaGate rigoroso della marca temporale di firma quando l’attributo è presente; $claimedTime resta l’ancora temporale
AdESValidationEngine::validateWithLongTermDatastring $signedData, string $signature, array $dssData (certs/ocsps/crls)Passaggio basic richiesto; gate della marca temporale di firma armato con TSA-at-genTime; gate POE, revoca DSS e archiviazioneValidationReportNon sollevaNetworkPolicy::STRICT_OFFLINE con dati incorporati insufficienti produce INDETERMINATE / TRY_LATER
AdESValidationEngine::validateArchivalTimestampChainstring $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = nullCatena di copertura DocTimeStamp basata su evidenze sugli esatti byte del ByteRangeValidationReportNon solleva su byte ostiliTOTAL_PASSED solo per una catena attendibile che copre fino all’EOF
MainIndicationEnum backed da stringa, tre casiValori URN ETSI; vedere l’elenco dei casi qui sotto
SubIndicationEnum backed da stringa, quindici casiValori URN ETSI; vedere l’elenco dei casi qui sotto
ValidationReport::__constructMainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = ''Esito di validazione immutabile (final readonly)Nuovo reportNon sollevaisPassed(), isFailed(), isIndeterminate(), toArray()
DiagnosticData::__constructarray $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (tutti con valore predefinito)Contenitore di evidenze immutabile; solo traccia di auditNuovo valoreNon sollevatoArray() serializza i riferimenti per la reportistica
SignatureDataExtractor::extractstring $signedData, string $signatureSPI: analizza il CMS ed estrae i componenti di validazioneExtractedSignatureDataSignatureExtractionException quando la firma non può essere analizzataInterfaccia; disaccoppia il parsing ASN.1 dal motore
CmsSignatureDataExtractor::extractstring $signedData, string $signatureEstrae e verifica crittograficamente una firma basic PAdES detachedExtractedSignatureDataSignatureExtractionException solo quando il CMS non può essere analizzato affattoUn fallimento crypto o di binding restituisce dati con cryptoValid / hashValid a false; non solleva mai per questo
PdfSignatureDictionaryScanner::scanstring $pdfBytesScansione a livello di byte dei dizionari /ByteRange + /Contents con controlli incrociati anti-spoof a fit precisolist<PdfSignatureOccurrence>Totale; non solleva mai; i candidati malformati vengono ignoratiOrdinati per fine copertura, dal più precoce
PathValidatorInterface::validatearray $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = []Validazione del percorso RFC 5280 §6.1.4 con elaborazione delle policyPathValidationResultPathValidationException su una catena strutturalmente non valida o un limite avversariale superatoLa catena è end-entity per prima, ancora per ultima
PathValidatorInterface::validateWithAiaChasingarray $chain, ?DateTimeImmutable $validationTime = nullRisoluzione AIA degli intermediari mancanti, poi validazionePathValidationResultPathValidationExceptionI fetch sono limitati da timeout e limiti di byte
CertificateChainValidatorCostruttore: motore, PathValidationOptions, orologio, logger; withDefaults() staticoL’implementazione SPI con i cap avversariali predefinitiPathValidationResult da entrambi i metodiPathValidationExceptionSollevata anche quando un OpenSSLCertificate non può essere esportato in PEM
PathValidationOptions::__constructCap (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) più flag di policy, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchorProfondità 32, fanout 64, 5 s per fetch, 10 MiB per fetch; tutti i flag falseNuove opzioniNon sollevaFactory: defaults(), strict(), withTrustAnchors()
PathValidationResult::__constructbool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasonsEsito immutabile; trustAnchorTrusted predefinito false (fail-closed)Nuovo valoreNon sollevaL’appartenenza alla fiducia è distinta dalla validità strutturale
PolicyProcessorCostruttore: PolicyTreeState $state, PathValidationOptions $options; processCertificate(string $certDer, int $depth, bool $selfIssued), finalizeWrapUp(), tree()Espansione, mapping e wrap-up dell’albero delle policy RFC 5280 §6.1.4void / list<non-empty-string> / PolicyTreePathValidationException su qualsiasi fallimento di elaborazione delle policy (fail-closed)Il wrap-up restituisce gli OID delle policy sopravvissute, escludendo anyPolicy
PolicyTreeattach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), più query di letturaLo stato valid_policy_tree con un indice di profonditàVaria per metodoPathValidationException quando il conteggio delle foglie vive supera il cap di fanoutEspone ANY_POLICY_OID (2.5.29.32.0)
NameConstraintsChecker::processCertificatestring $certDer, bool $applyNameCheckAccumula e applica i sottoalberi permessi / esclusi secondo RFC 5280 §6.1.4(g)voidPathValidationException su un sottoalbero violato, una forma GeneralName non supportata in un vincolo o un cap superatoI nomi non comparabili sono gestiti fail-closed
TrustAnchorStoreInterface::containsFingerprintstring $anchorDerSha256HexAppartenenza tramite SHA-256 esadecimale minuscolo sul certificato DER dell’ancoraboolNon sollevaLa cucitura di fiducia consultata dal validatore di percorso
BatchSignatureValidator::validatearray $inputs (list<DocumentSignatureInput>)Validazione di firme multi-documento con caching della revoca per batchBatchValidationReportInvalidArgumentException su una lista vuota; una guardia di risorse rifiuta i batch oltre 1000 documentiRisiede in NextPDF\Enterprise\Signature
final class AdESValidationEngine
public function validateBasic(string $signedData, string $signature): ValidationReport
public function validateWithTime(
string $signedData,
string $signature,
DateTimeImmutable $claimedTime,
): ValidationReport
public function validateWithLongTermData(
string $signedData,
string $signature,
array $dssData,
): ValidationReport
public function validateArchivalTimestampChain(
string $pdfBytes,
array $dssData = [],
?TrustAnchorStoreInterface $anchors = null,
): ValidationReport
public function validate(
array $chain,
?DateTimeImmutable $validationTime = null,
array $initialPolicies = [],
): PathValidationResult;
public function validateWithAiaChasing(
array $chain,
?DateTimeImmutable $validationTime = null,
): PathValidationResult;
public static function withDefaults(
?ClockInterface $clock = null,
?AiaChaser $aiaChaser = null,
?LoggerInterface $logger = null,
): self
public function containsFingerprint(string $anchorDerSha256Hex): bool;
public function extract(string $signedData, string $signature): ExtractedSignatureData;
public function scan(string $pdfBytes): array
public function validate(array $inputs): BatchValidationReport

Enum di indicazione. Casi di MainIndication: TOTAL_PASSED, TOTAL_FAILED, INDETERMINATE. I valori di backing seguono lo schema urn:etsi:019102:mainindication:total-passed (minuscolo, con trattini). Casi di SubIndication: HASH_FAILURE, SIG_CRYPTO_FAILURE, REVOKED, EXPIRED, NOT_YET_VALID, NO_POE, TRY_LATER, CERTIFICATE_CHAIN_GENERAL_FAILURE, FORMAT_FAILURE, REVOKED_CA_NO_POE, CRYPTO_CONSTRAINTS_FAILURE, POLICY_PROCESSING_FAILURE, REVOCATION_OUT_OF_BOUNDS_NO_POE, NO_SIGNING_CERTIFICATE_FOUND, TIMESTAMP_ORDER_FAILURE. Ciascuno è backed da urn:etsi:019102:subindication:<CASE_NAME> con il nome esatto del caso.

  • Report in ingresso, report in uscita. I quattro punti di ingresso del motore restituiscono un ValidationReport per input ostili invece di sollevare. Una SignatureExtractionException catturata instrada verso il percorso di guardia; una PathValidationException catturata mappa a TOTAL_FAILED / CERTIFICATE_CHAIN_GENERAL_FAILURE.
  • Ordine della validazione basic. Prima il controllo del formato; una struttura non analizzabile è TOTAL_FAILED / FORMAT_FAILURE (EN 319 102-1 §5.3.4). Poi il digest (HASH_FAILURE) e la verifica crittografica (SIG_CRYPTO_FAILURE), corrispondenti agli esiti dei building block di EN 319 102-1 §5.2.7.4. Il digest viene ricalcolato dal verifier e confrontato con l’attributo firmato messageDigest (RFC 5652 §5.6); i digest forniti dal produttore non sono mai considerati attendibili.
  • Gli algoritmi deboli degradano. Una firma che verifica sotto SHA-1, o con un binding debole del certificato di firma, restituisce INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE, mai TOTAL_PASSED. Il percorso temporale riafferma questo, così una firma debole non viene mai riciclata in un esito valido nel tempo.
  • Gate di provenienza della revoca. I flag di revoca dell’extractor sono consultati solo quando l’extractor ha effettivamente eseguito un controllo di revoca (revocationChecked true). Un valore predefinito non controllato non è né “verificato non revocato” né un trigger REVOKED. L’evidenza di revoca è stabilita dal percorso DSS.
  • Propagazione del non-esito-positivo. I percorsi con tempo e a lungo termine non promuovono mai un risultato basic non positivo. Esiste un’unica eccezione: un basic INDETERMINATE / REVOKED viene risolto rispetto a $claimedTime; la revoca al momento del tempo dichiarato o prima di esso è TOTAL_FAILED / REVOKED. Ciò rispecchia lo schema di EN 319 102-1 §5.3.4 di risolvere un indeterminato relativo alla revoca con evidenza temporale. Quando il confronto non può essere eseguito, il report basic irrisolto viene propagato verbatim.
  • Binding rigoroso della marca temporale di firma (fail-closed; rottura BC). Quando il CMS trasporta un attributo non firmato id-aa-timeStampToken, la sua presenza attiva l’enforcement sia nel percorso con tempo sia in quello a lungo termine; non esiste una modalità solo-avviso. La cardinalità deve essere esattamente un attributo con esattamente un valore (EN 319 122-1 §5.3); qualsiasi altra forma è TOTAL_FAILED / FORMAT_FAILURE. Il token deve verificare crittograficamente da un capo all’altro; un token non verificabile, un conflitto parser-differential o una mancata corrispondenza dell’imprint è INDETERMINATE / TIMESTAMP_ORDER_FAILURE. Un algoritmo di imprint non supportato o SHA-1 è INDETERMINATE / CRYPTO_CONSTRAINTS_FAILURE. La regola di binding è RFC 3161 Appendix A: il messageImprint del token deve essere uguale all’hash degli ottetti del valore signature di SignerInfo, confrontati a tempo costante.
  • Gate del percorso a lungo termine. Nel percorso annotato con la clausola 5.4 la marca temporale di firma vincolata riceve inoltre la valutazione del certificato TSA al genTime del token; un’ancora non attendibile è INDETERMINATE / CERTIFICATE_CHAIN_GENERAL_FAILURE, mai un esito positivo. NetworkPolicy::STRICT_OFFLINE con materiale DSS incorporato insufficiente restituisce INDETERMINATE / TRY_LATER. Le rilevazioni di prova di esistenza, revoca DSS e catena di archiviazione fanno ciascuna short-circuit a INDETERMINATE con una sotto-indicazione mappata.
  • Gate della catena di archiviazione. Nessun DocTimeStamp presente è INDETERMINATE / NO_POE. Un ByteRange strutturalmente non conforme è TOTAL_FAILED / FORMAT_FAILURE. Ogni token deve verificare, vincolare il proprio imprint agli esatti byte coperti dal ByteRange e superare il mapping delle facet TSA-at-genTime (EXPIRED, NOT_YET_VALID, REVOKED_CA_NO_POE, CERTIFICATE_CHAIN_GENERAL_FAILURE o TRY_LATER in strict-offline). L’ordinamento è imposto: genTime non decrescente, copertura in progressione stretta e token successivi che contengono il buco /Contents del token precedente. Il token più recente deve coprire il byte finale; i byte in coda sono TIMESTAMP_ORDER_FAILURE. Un genTime più di 300 secondi avanti rispetto all’orologio del verifier è TIMESTAMP_ORDER_FAILURE.
  • La diagnostica non decide mai. Le voci di prova di esistenza di DiagnosticData::$timestamps sono solo traccia di audit. Non cambiano mai un’indicazione, e l’accumulatore si azzera a ogni punto di ingresso.
  • I limiti Pki precedono la crittografia. I cap di PathValidationOptions (profondità 32, fanout delle policy 64, 5 s e 10 MiB per fetch) sono controllati prima del lavoro costoso. PathValidationResult::$trustAnchorTrusted è distinto da $valid; requireTrustedAnchor rende non valido un terminus non confermato. strict() abilita requireExplicitPolicy, il trasporto di revoca hard-fail e requireTrustedAnchor. La validità del percorso è relativa all’ancora secondo RFC 5280 §6.1: un percorso valido inizia da un’ancora di fiducia fornita come input.
  • Superficie batch. BatchSignatureValidator::validate() solleva InvalidArgumentException per una lista vuota e rifiuta i batch oltre 1000 documenti tramite una guardia di risorse. PHP possiede tutta la validazione crittografica in quella pipeline.
  • Il motore predefinito non ha extractor. new AdESValidationEngine() esegue solo controlli di guardia: firma o dati firmati vuoti sono TOTAL_FAILED; qualsiasi coppia non vuota si risolve in INDETERMINATE / NO_SIGNING_CERTIFICATE_FOUND, mai TOTAL_PASSED. Iniettare NextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractor per ottenere la verifica crittografica.
  • Il controllo di fiducia TSA predefinito non ha store. Ogni catena TSA riporta quindi non attendibile, così gli esiti della marca temporale di firma di archiviazione e a lungo termine restano INDETERMINATE. Fornire le ancore tramite validateArchivalTimestampChain(..., $anchors) o un TsaCertificateAtGenTimeCheck configurato.
  • $pdfBytes vuoto. validateArchivalTimestampChain('') restituisce TOTAL_FAILED / FORMAT_FAILURE.
  • Le marche temporali di firma precedenti alla correzione non possono passare. I token prodotti da versioni di NextPDF antecedenti alla correzione del binding rigoroso hanno imprintato un input differente. Falliscono permanentemente il binding di Appendix A; ri-firmare e ri-marcare temporalmente per ripristinare un risultato positivo. Questa è una rottura BC deliberata e documentata.
  • DocTimeStamp duplicati o sovrapposti. Un duplicato nella stessa revisione, copertura uguale o sovrapposta, o un token successivo che non contiene il buco di firma del token precedente falliscono il gate di ordinamento.
  • Lo scanner è totale e a livello di byte. scan() ignora silenziosamente i candidati malformati o spoofati; un /ByteRange esca all’interno di un content stream viene rifiutato. Non risolve oggetti indiretti né percorre la tabella dei cross-reference.
  • Copertura, non raggiungibilità. validateArchivalTimestampChain() dimostra la copertura crittografica del byte-range fino alla fine del file. L’analisi di raggiungibilità a livello di oggetto (per esempio, una radice di documento ri-puntata all’interno di una revisione coperta) è dichiarata fuori ambito.
  • L’uso diretto di Pki solleva. Chiamare direttamente le implementazioni di PathValidatorInterface fa emergere PathValidationException per catene strutturalmente non valide, cap superati, forme di vincolo non supportate ed esportazione PEM fallita di un handle OpenSSLCertificate. Il motore cattura questa classe; i tuoi chiamanti devono gestirla.

La superficie di verifica accetta RSA PKCS#1 v1.5 con SHA-2 ed ECDSA su P-256/P-384/P-521. I token RSASSA-PSS, EdDSA e SHA-3 falliscono chiuso come non supportati; SHA-1 degrada a CRYPTO_CONSTRAINTS_FAILURE. Sotto il profilo crypto-policy FIPS 140-3 Enterprise (documentato con il modulo security), il vincolo si applica a quali algoritmi vengono accettati; il flusso di validazione in sé — ricalcolo del digest, controlli della firma, binding, validazione del percorso — resta invariato. NextPDF non detiene alcun certificato FIPS 140-3 e questa pagina non ne rivendica alcuno.

AffermazioneStandardClausola
La validazione della Basic Signature è un building block riutilizzabile per la validazione con marca temporale e con tempo.ETSI EN 319 102-1§5.3.1
Il fallimento di integrità mappa a HASH_FAILURE; un controllo della firma fallito mappa a SIG_CRYPTO_FAILURE.ETSI EN 319 102-1§5.2.7.4
Il controllo del formato viene eseguito per primo e un non-esito-positivo arresta il processo.ETSI EN 319 102-1§5.3.4
Un indeterminato relativo alla revoca può essere risolto con evidenza temporale.ETSI EN 319 102-1§5.3.4
Un percorso di certificazione valido inizia da un’ancora di fiducia fornita come input.RFC 5280§6.1
Il verifier ricalcola il digest del contenuto; deve essere uguale all’attributo firmato messageDigest.RFC 5652§5.6
Il messageImprint della marca temporale di firma esegue l’hash del valore del campo signature di SignerInfo.RFC 3161Appendix A
L’attributo signature-time-stamp trasporta esattamente un AttributeValue.ETSI EN 319 122-1§5.3

Tutte le clausole sono parafrasate; NextPDF non riproduce testo normativo. NextPDF non rivendica alcuna conformità o certificazione AdES / PAdES. Il supporto di uno standard non è conformità ad esso, e la conformità non è certificazione — NextPDF non detiene alcuna certificazione e non ne concede alcuna. Il motore implementa le procedure di validazione citate come capacità; non è un servizio di validazione qualificato o certificato, e un report TOTAL_PASSED è un’affermazione crittografica, non una determinazione legale. I valori enum riutilizzano lo schema di identificatore URN ETSI per l’interoperabilità dei dati di report; tale riutilizzo non afferma alcuna approvazione.

  • Mapping delle etichette di clausola. Il sorgente del package annota i punti di ingresso come clausole 5.2, 5.3 e 5.4 di EN 319 102-1. Il corpus di conformità colloca il processo di validazione della Basic Signature stesso alla clausola 5.3, con il building block crittografico a 5.2.7.4. Questa pagina cita i numeri di clausola recuperati; il contratto di comportamento, non l’etichetta, è autoritativo.
  • Test deterministici. Ogni confronto temporale passa attraverso l’iniettato ClockInterface PSR-20. Iniettare un orologio congelato per testare i controlli di finestra, il limite di scarto del genTime di 300 secondi e le decisioni di freschezza CRL.
  • Composizione. Tutti i collaboratori del motore sono iniettati via costruttore e opzionali, con valori predefiniti fail-closed. Il validatore di percorso predefinito è CertificateChainValidator::withDefaults() sull’orologio del motore; le opzioni predefinite mantengono l’elaborazione delle policy e dei name-constraint un no-op per input conformi e non vincolati.
  • Namespace. La superficie del motore risiede in NextPDF\Enterprise\Security\Validation, la superficie di validazione del percorso in NextPDF\Enterprise\Security\Pki e l’orchestratore batch in NextPDF\Enterprise\Signature.
  • Igiene dei report. I report sono immutabili e serializzabili tramite toArray(). Il contesto diagnostico si azzera a ogni punto di ingresso, così un report non trasporta mai evidenza da un’esecuzione precedente sulla stessa istanza del motore.

Questa pagina documenta solo il comportamento osservabile dall’esterno e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle di meccanismo, i nomi di file di runbook e i prefissi di ticket sono fuori ambito.