Enterprise editie
Handtekeningverificatie — Diepe referentie
In één oogopslag
Sectie met titel “In één oogopslag”Deze pagina is de diepe referentie voor de AdES verify-side in NextPDF Enterprise. Het entry point is NextPDF\Enterprise\Security\Validation\AdESValidationEngine. Het implementeert NextPDF’s ETSI-gemodelleerde validatieflows voor basis-, met-tijd-, langetermijn- en archief-timestampcontroles: basisvalidatie, validatie met tijd, validatie met langetermijndata en archief-DocTimeStamp coverage-chain-validatie. Uitkomsten zijn ValidationReport-waarden die MainIndication- en SubIndication-enumgevallen dragen met ETSI-URN-stringwaarden. Ondersteunende oppervlakken die hier worden gedocumenteerd: de SignatureDataExtractor-SPI en zijn CmsSignatureDataExtractor-implementatie, de PdfSignatureDictionaryScanner byte-level scanner, het NextPDF\Enterprise\Security\Pki path-validatie-oppervlak en BatchSignatureValidator. Voor begeleiding op workflowniveau, zie Handtekeningverificatie: AdES / PAdES cryptografische verify-side.
Beschikbaarheid en licentie
Sectie met titel “Beschikbaarheid en licentie”Deze mogelijkheid wordt geleverd in NextPDF Enterprise (nextpdf/enterprise) en activeert met een licentie-envelop van het Enterprise-niveau. Een deployment zonder die entitlement laadt de klassen van de mogelijkheid niet. Vergelijk edities en verkrijg een licentie.
Publiek API-oppervlak
Sectie met titel “Publiek API-oppervlak”| Symbool | Parameters | Standaardgedrag | Retourneert | Gooit of faalt met | Opmerkingen |
|---|---|---|---|---|---|
AdESValidationEngine::__construct | 11 optionele parameters: ?PathValidatorInterface $chainValidator, ?SignatureDataExtractor $extractor, ClockInterface $clock, ?LoggerInterface $logger, string $defaultPolicy, NetworkPolicy $networkPolicy, en vijf optionele verifier-collaborators | Alle standaardwaarden zijn fail-closed: Pki path-validator over de engine-clock, geen extractor, geen TSA-trust-store | Nieuwe engine | Gooit niet | Zonder trust-store rapporteert TSA-chain-evaluatie untrusted; dat mapt naar INDETERMINATE, nooit een pass |
AdESValidationEngine::validateBasic | string $signedData, string $signature | Basisvalidatie: format, digest, crypto, weak-algorithm, chain, provenance-gated revocation | ValidationReport | Gooit niet; extractie- en path-fouten mappen naar fail-closed rapporten | Zonder extractor alleen guard checks; zie edge cases |
AdESValidationEngine::validateWithTime | string $signedData, string $signature, DateTimeImmutable $claimedTime | Eerst basisvalidatie; certificaatvenster en revocation vergeleken met de claimed time | ValidationReport | Gooit niet | Strikte signature-timestamp-gate wanneer het attribuut aanwezig is; $claimedTime blijft het tijdanker |
AdESValidationEngine::validateWithLongTermData | string $signedData, string $signature, array $dssData (certs/ocsps/crls) | Basis-pass vereist; signature-timestamp-gate scherpgesteld met TSA-at-genTime; POE-, DSS-revocation- en archiefgates | ValidationReport | Gooit niet | NetworkPolicy::STRICT_OFFLINE met onvoldoende embedded data levert INDETERMINATE / TRY_LATER |
AdESValidationEngine::validateArchivalTimestampChain | string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null | Bewijs-gebaseerde DocTimeStamp coverage-chain over de exacte ByteRange-bytes | ValidationReport | Gooit niet bij vijandige bytes | TOTAL_PASSED alleen voor een vertrouwde, EOF-dekkende chain |
MainIndication | — | String-backed enum, drie gevallen | — | — | ETSI-URN-waarden; zie de gevallenlijst hieronder |
SubIndication | — | String-backed enum, vijftien gevallen | — | — | ETSI-URN-waarden; zie de gevallenlijst hieronder |
ValidationReport::__construct | MainIndication $mainIndication, ?SubIndication $subIndication, DiagnosticData $diagnosticData, DateTimeImmutable $validationTime, string $validationPolicy = '' | Immutable (final readonly) validatie-uitkomst | Nieuw rapport | Gooit niet | isPassed(), isFailed(), isIndeterminate(), toArray() |
DiagnosticData::__construct | array $certificateChain, array $timestamps, array $revocationData, string $validationPolicy, string $signatureFormat, array $warnings (allemaal met standaardwaarde) | Immutable bewijscontainer; alleen audit trail | Nieuwe waarde | Gooit niet | toArray() serialiseert referenties voor rapportage |
SignatureDataExtractor::extract | string $signedData, string $signature | SPI: parse de CMS en extraheer validatiecomponenten | ExtractedSignatureData | SignatureExtractionException wanneer de handtekening niet geparseerd kan worden | Interface; ontkoppelt ASN.1-parsing van de engine |
CmsSignatureDataExtractor::extract | string $signedData, string $signature | Extraheer plus verifieer cryptografisch een detached PAdES basic signature | ExtractedSignatureData | SignatureExtractionException alleen wanneer de CMS helemaal niet geparseerd kan worden | Een crypto- of binding-fout retourneert data met cryptoValid / hashValid false; het gooit daarvoor nooit |
PdfSignatureDictionaryScanner::scan | string $pdfBytes | Byte-level scan naar /ByteRange + /Contents dictionaries met precise-fit anti-spoof cross-checks | list<PdfSignatureOccurrence> | Totaal; gooit nooit; misvormde kandidaten worden overgeslagen | Geordend op coverage-einde, vroegste eerst |
PathValidatorInterface::validate | array $chain, ?DateTimeImmutable $validationTime = null, array $initialPolicies = [] | RFC 5280 §6.1.4 path-validatie met policy-verwerking | PathValidationResult | PathValidationException bij een structureel ongeldige chain of een geschonden adversarial limit | Chain is end-entity eerst, anchor laatst |
PathValidatorInterface::validateWithAiaChasing | array $chain, ?DateTimeImmutable $validationTime = null | AIA-resolutie van ontbrekende intermediates, dan validatie | PathValidationResult | PathValidationException | Fetches worden begrensd door timeout en byte-limieten |
CertificateChainValidator | Constructor: engine, PathValidationOptions, clock, logger; statisch withDefaults() | De SPI-implementatie met de standaard adversarial caps | PathValidationResult van beide methoden | PathValidationException | Ook gegooid wanneer een OpenSSLCertificate niet naar PEM geëxporteerd kan worden |
PathValidationOptions::__construct | Caps (maxDepth, maxPolicyFanout, fetchTimeoutSeconds, fetchSizeCapBytes) plus policy-flags, ?TrustAnchorStoreInterface $trustAnchors, bool $requireTrustedAnchor | Diepte 32, fanout 64, 5 s per fetch, 10 MiB per fetch; alle flags false | Nieuwe opties | Gooit niet | Factories: defaults(), strict(), withTrustAnchors() |
PathValidationResult::__construct | bool $valid, string $trustAnchorFingerprint, DateTimeImmutable $validatedAt, array $validPolicies, ?RevocationCheckResult $revocation, bool $trustAnchorTrusted, array $fetchedCertificates, array $failureReasons | Immutable uitkomst; trustAnchorTrusted standaard false (fail-closed) | Nieuwe waarde | Gooit niet | Trust-lidmaatschap is los van structurele validiteit |
PolicyProcessor | Constructor: PolicyTreeState $state, PathValidationOptions $options; processCertificate(string $certDer, int $depth, bool $selfIssued), finalizeWrapUp(), tree() | RFC 5280 §6.1.4 policy-tree-expansie, mapping en wrap-up | void / list<non-empty-string> / PolicyTree | PathValidationException bij elke policy-verwerkingsfout (fail-closed) | Wrap-up retourneert overlevende policy-OID’s, exclusief anyPolicy |
PolicyTree | attach(PolicyTreeNode $node, PathValidationOptions $options), enforceFanout(...), remove(...), plus read queries | De valid_policy_tree-status met een diepte-index | Varieert per methode | PathValidationException wanneer het live leaf-aantal de fanout-cap overschrijdt | Stelt ANY_POLICY_OID (2.5.29.32.0) bloot |
NameConstraintsChecker::processCertificate | string $certDer, bool $applyNameCheck | Verzamelt en handhaaft permitted / excluded subtrees per RFC 5280 §6.1.4(g) | void | PathValidationException bij een geschonden subtree, een niet-ondersteunde GeneralName-vorm in een constraint, of een geschonden cap | Niet-vergelijkbare namen worden fail-closed afgehandeld |
TrustAnchorStoreInterface::containsFingerprint | string $anchorDerSha256Hex | Lidmaatschap via lowercase hex SHA-256 over het DER-certificaat van de anchor | bool | Gooit niet | De trust-seam die door de path-validator wordt geraadpleegd |
BatchSignatureValidator::validate | array $inputs (list<DocumentSignatureInput>) | Multi-document handtekeningvalidatie met per-batch revocation-caching | BatchValidationReport | InvalidArgumentException bij een lege lijst; een resource guard wijst batches boven 1000 documenten af | Leeft in NextPDF\Enterprise\Signature |
final class AdESValidationEnginepublic function validateBasic(string $signedData, string $signature): ValidationReportpublic function validateWithTime( string $signedData, string $signature, DateTimeImmutable $claimedTime,): ValidationReportpublic function validateWithLongTermData( string $signedData, string $signature, array $dssData,): ValidationReportpublic function validateArchivalTimestampChain( string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null,): ValidationReportpublic 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,): selfpublic function containsFingerprint(string $anchorDerSha256Hex): bool;public function extract(string $signedData, string $signature): ExtractedSignatureData;public function scan(string $pdfBytes): arraypublic function validate(array $inputs): BatchValidationReportIndicatie-enums. MainIndication-gevallen: TOTAL_PASSED, TOTAL_FAILED, INDETERMINATE. Achterliggende waarden volgen het patroon urn:etsi:019102:mainindication:total-passed (lowercase, met koppeltekens). SubIndication-gevallen: 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. Elk wordt onderbouwd door urn:etsi:019102:subindication:<CASE_NAME> met de exacte casusnaam.
Gedragscontract
Sectie met titel “Gedragscontract”- Rapporten in, rapporten uit. De vier engine-entry-points retourneren een
ValidationReportvoor vijandige input in plaats van te gooien. Een opgevangenSignatureExtractionExceptiongaat naar het guard-pad; een opgevangenPathValidationExceptionmapt naarTOTAL_FAILED/CERTIFICATE_CHAIN_GENERAL_FAILURE. - Volgorde van basisvalidatie. Eerst de format-check; een niet-parseerbare structuur is
TOTAL_FAILED/FORMAT_FAILURE(EN 319 102-1 §5.3.4). Dan digest (HASH_FAILURE) en cryptografische verificatie (SIG_CRYPTO_FAILURE), overeenkomend met de EN 319 102-1 §5.2.7.4 building-block-uitkomsten. De digest wordt door de verifier herberekend en vergeleken met hetmessageDigestsigned attribute (RFC 5652 §5.6); door de producer geleverde digests worden nooit vertrouwd. - Zwakke algoritmen degraderen. Een handtekening die verifieert onder SHA-1, of met een zwakke signing-certificate-binding, retourneert
INDETERMINATE/CRYPTO_CONSTRAINTS_FAILURE, nooitTOTAL_PASSED. Het tijdpad bevestigt dit opnieuw zodat een zwakke handtekening nooit wordt witgewassen tot een tijd-valide pass. - Revocation-provenance-gate. Revocation-flags van de extractor worden alleen geraadpleegd wanneer de extractor daadwerkelijk een revocation-check heeft uitgevoerd (
revocationCheckedtrue). Een ongecontroleerde standaardwaarde is noch “geverifieerd niet gerevoceerd” noch eenREVOKED-trigger. Revocation-bewijs wordt vastgesteld via het DSS-pad. - Non-pass-propagatie. De tijd- en langetermijnpaden upgraden nooit een non-pass basisresultaat. Er bestaat één uitzondering: een basis-
INDETERMINATE/REVOKEDwordt opgelost tegen$claimedTime; revocation op of vóór de claimed time isTOTAL_FAILED/REVOKED. Dit weerspiegelt het EN 319 102-1 §5.3.4 patroon van het oplossen van een revocation-gerelateerde indeterminate met tijdbewijs. Wanneer de vergelijking niet kan worden uitgevoerd, wordt het onopgeloste basisrapport verbatim gepropageerd. - Strikte signature-timestamp-binding (fail-closed; BC break). Wanneer de CMS een
id-aa-timeStampTokenunsigned attribute draagt, triggert de aanwezigheid ervan handhaving in zowel het tijd- als het langetermijnpad; er is geen warn-only modus. De cardinaliteit moet exact één attribuut met exact één waarde zijn (EN 319 122-1 §5.3); elke andere vorm isTOTAL_FAILED/FORMAT_FAILURE. Het token moet cryptografisch end-to-end verifiëren; een niet-verifieerbaar token, een parser-differential-conflict of een imprint-mismatch isINDETERMINATE/TIMESTAMP_ORDER_FAILURE. Een niet-ondersteund of SHA-1 imprint-algoritme isINDETERMINATE/CRYPTO_CONSTRAINTS_FAILURE. De bindingregel is RFC 3161 Appendix A: hetmessageImprintvan het token moet gelijk zijn aan de hash van de SignerInfosignature-waarde-octetten, in constante tijd vergeleken. - Langetermijnpad-gates. In het clause-5.4-geannoteerde pad ontvangt de gebonden signature timestamp bovendien TSA-certificaatevaluatie op de
genTimevan het token; een niet-vertrouwde anchor isINDETERMINATE/CERTIFICATE_CHAIN_GENERAL_FAILURE, nooit een pass.NetworkPolicy::STRICT_OFFLINEmet onvoldoende embedded DSS-materiaal retourneertINDETERMINATE/TRY_LATER. Proof-of-existence-, DSS-revocation- en archiefketen-bevindingen kortsluiten elk naarINDETERMINATEmet een gemapte sub-indicatie. - Archiefketen-gates. Geen DocTimeStamp aanwezig is
INDETERMINATE/NO_POE. Een structureel niet-conforme ByteRange isTOTAL_FAILED/FORMAT_FAILURE. Elk token moet verifiëren, zijn imprint binden aan de exacte ByteRange-gedekte bytes, en de TSA-at-genTime facet-mapping doorstaan (EXPIRED,NOT_YET_VALID,REVOKED_CA_NO_POE,CERTIFICATE_CHAIN_GENERAL_FAILURE, ofTRY_LATERonder strict-offline). Ordening wordt gehandhaafd: niet-dalendegenTime, strikt voortschrijdende coverage, en latere tokens die het/Contents-gat van het voorgaande token bevatten. Het nieuwste token moet de laatste byte dekken; trailing bytes zijnTIMESTAMP_ORDER_FAILURE. EengenTimemeer dan 300 seconden vóór de verifier-clock isTIMESTAMP_ORDER_FAILURE. - Diagnostiek beslist nooit.
DiagnosticData::$timestampsproof-of-existence-entries zijn alleen audit trail. Ze veranderen nooit een indicatie, en de accumulator reset bij elk entry point. - Pki-limieten gaan vooraf aan crypto.
PathValidationOptions-caps (diepte 32, policy-fanout 64, 5 s en 10 MiB per fetch) worden gecontroleerd vóór duur werk.PathValidationResult::$trustAnchorTrustedstaat los van$valid;requireTrustedAnchormaakt een niet-bevestigd terminus ongeldig.strict()schakeltrequireExplicitPolicy, hard-fail revocation-transport enrequireTrustedAnchorin. Path-validiteit is anchor-relatief per RFC 5280 §6.1: een geldig pad begint bij een als input geleverde trust anchor. - Batch-oppervlak.
BatchSignatureValidator::validate()gooitInvalidArgumentExceptionvoor een lege lijst en wijst batches boven 1000 documenten af via een resource guard. PHP bezit alle cryptografische validatie in die pipeline.
Edge cases en foutmodi
Sectie met titel “Edge cases en foutmodi”- Standaard-engine heeft geen extractor.
new AdESValidationEngine()voert alleen guard checks uit: lege signature of signed data isTOTAL_FAILED; elk niet-leeg paar resolvet naarINDETERMINATE/NO_SIGNING_CERTIFICATE_FOUND, nooitTOTAL_PASSED. InjecteerNextPDF\Enterprise\Security\Validation\CmsSignatureDataExtractorom cryptografische verificatie te verkrijgen. - Standaard-TSA-trust-check heeft geen store. Elke TSA-chain rapporteert dan untrusted, dus archief- en langetermijn-signature-timestamp-uitkomsten blijven
INDETERMINATE. Lever anchors aan viavalidateArchivalTimestampChain(..., $anchors)of een geconfigureerdeTsaCertificateAtGenTimeCheck. - Lege
$pdfBytes.validateArchivalTimestampChain('')retourneertTOTAL_FAILED/FORMAT_FAILURE. - Pre-fix signature timestamps kunnen niet passen. Tokens geproduceerd door NextPDF-versies vóór de strict-binding fix imprintten een andere input. Ze falen de Appendix A-binding permanent; onderteken en timestamp opnieuw om een positief resultaat te herstellen. Dit is een bewuste, gedocumenteerde BC break.
- Dubbele of overlappende DocTimeStamps. Een same-revision duplicaat, gelijke of overlappende coverage, of een later token dat het signature-gat van het voorgaande token niet bevat, faalt de ordening-gate.
- Scanner is totaal en byte-level.
scan()slaat misvormde of gespoofte kandidaten stil over; een decoy-/ByteRangebinnen een content stream wordt afgewezen. Het lost geen indirecte objecten op en loopt niet door de cross-reference table. - Coverage, geen reachability.
validateArchivalTimestampChain()bewijst cryptografische byte-range-coverage tot end-of-file. Object-level reachability-analyse (bijvoorbeeld een her-verwezen document root binnen een gedekte revisie) is als out of scope verklaard. - Direct Pki-gebruik gooit. Het direct aanroepen van
PathValidatorInterface-implementaties brengtPathValidationExceptionnaar de oppervlakte voor structureel ongeldige chains, geschonden caps, niet-ondersteunde constraint-vormen en gefaalde PEM-export van eenOpenSSLCertificate-handle. De engine vangt deze klasse op; je eigen callers moeten het afhandelen.
FIPS-mode-gedrag
Sectie met titel “FIPS-mode-gedrag”De verify-side accepteert RSA PKCS#1 v1.5 met SHA-2 en ECDSA op P-256/P-384/P-521. RSASSA-PSS-, EdDSA- en SHA-3-tokens falen fail-closed als niet-ondersteund; SHA-1 degradeert naar CRYPTO_CONSTRAINTS_FAILURE. Onder het Enterprise FIPS 140-3 crypto-policy-profiel (gedocumenteerd bij de security-module) geldt de constraint voor welke algoritmen worden geaccepteerd; de validatieflow zelf — digest-herberekening, signature-checks, binding, path-validatie — is ongewijzigd. NextPDF houdt geen FIPS 140-3-certificaat en deze pagina claimt er geen.
Conformiteit
Sectie met titel “Conformiteit”| Claim | Standaard | Clausule |
|---|---|---|
| Basic Signature validation is een herbruikbare building block voor time-stamp- en with-time-validatie. | ETSI EN 319 102-1 | §5.3.1 |
Integriteitsfout mapt naar HASH_FAILURE; een gefaalde signature-check mapt naar SIG_CRYPTO_FAILURE. | ETSI EN 319 102-1 | §5.2.7.4 |
| Format-checking loopt eerst en een non-pass stopt het proces. | ETSI EN 319 102-1 | §5.3.4 |
| Een revocation-gerelateerde indeterminate kan worden opgelost met tijdbewijs. | ETSI EN 319 102-1 | §5.3.4 |
| Een geldig certificatiepad begint bij een als input geleverde trust anchor. | RFC 5280 | §6.1 |
De verifier herberekent de content digest; die moet gelijk zijn aan het messageDigest signed attribute. | RFC 5652 | §5.6 |
Het messageImprint van de signature timestamp hasht de SignerInfo signature-veldwaarde. | RFC 3161 | Appendix A |
Het signature-time-stamp-attribuut draagt exact één AttributeValue. | ETSI EN 319 122-1 | §5.3 |
Alle clausules zijn geparafraseerd; NextPDF reproduceert geen normatieve tekst. NextPDF maakt geen AdES / PAdES conformiteits- of certificeringsclaim. Ondersteuning voor een standaard is geen conformiteit ermee, en conformiteit is geen certificering — NextPDF houdt geen certificering en verleent er geen. De engine implementeert de geciteerde validatieprocedures als mogelijkheid; het is geen gekwalificeerde of gecertificeerde validatiedienst, en een TOTAL_PASSED-rapport is een cryptografische verklaring, geen juridische bepaling. De enum-waarden hergebruiken het ETSI-URN-identificatiepatroon voor interoperabiliteit van rapportdata; dat hergebruik beweert geen endorsement.
Ontwikkelnotities
Sectie met titel “Ontwikkelnotities”- Clausule-label-mapping. De package-broncode annoteert de entry points als EN 319 102-1 clausules 5.2, 5.3 en 5.4. Het compliance-corpus plaatst het Basic Signature validation-proces zelf op clausule 5.3, met de cryptografische building block op 5.2.7.4. Deze pagina citeert de opgehaalde clausulenummers; het gedragscontract, niet het label, is gezaghebbend.
- Deterministische tests. Elke tijdvergelijking loopt door de geïnjecteerde PSR-20
ClockInterface. Injecteer een bevroren clock om venstercontroles, de 300-seconden genTime-skew-grens en CRL-freshness-beslissingen te testen. - Compositie. Alle engine-collaborators zijn constructor-geïnjecteerd en optioneel, met fail-closed standaardwaarden. De standaard path-validator is
CertificateChainValidator::withDefaults()over de engine-clock; standaardopties houden policy- en name-constraint-verwerking een no-op voor conforme, ongeconstrainde inputs. - Namespaces. Het engine-oppervlak leeft in
NextPDF\Enterprise\Security\Validation, het path-validatie-oppervlak inNextPDF\Enterprise\Security\Pki, en de batch-orchestrator inNextPDF\Enterprise\Signature. - Rapporthygiëne. Rapporten zijn immutable en serialiseerbaar via
toArray(). Diagnostische context reset bij elk entry point, dus een rapport draagt nooit bewijs van een eerdere run op dezelfde engine-instantie.
Zie ook
Sectie met titel “Zie ook”- Handtekeningverificatie: AdES / PAdES cryptografische verify-side — de capability-pagina: workflow, algoritmetabel, upgradenotities.
- Handtekening — Diepe referentie — de PAdES B-LT / B-LTA producer-kant.
- Validatie — Diepe referentie — structurele policy-checks zonder cryptografie.
- Beveiliging — Diepe referentie — het gecombineerde Enterprise-security-oppervlak, inclusief het FIPS-profiel.
- PAdES baseline-mapping — B-B, B-T, B-LT, B-LTA over edities heen.
Publicatiegrens
Sectie met titel “Publicatiegrens”Deze pagina documenteert alleen extern waarneembaar gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helper-klassen, mechanismetabellen, runbook-bestandsnamen en ticket-prefixen zijn out of scope.