Ga naar inhoud
getnextpdf.com

Hoe een digitale handtekening bewijst wie ondertekende

Spec: RFC 5652Spec: RFC 5280, §6Spec: RFC 3161, §1

Een digitale handtekening doet drie dingen, en het loont om ze vanaf het begin uit elkaar te houden: ze bewijst dat de bytes niet zijn gewijzigd, ze bewijst wie ze ondertekende, en — met een beetje hulp — ze bewijst wanneer. Deze pagina bouwt dat idee op vanaf nul, zodat de cryptografie ophoudt een black box te zijn.

“Ondertekend” is een woord waarop mensen beslissingen baseren. Een contract, een factuur, een release-notitie voor software die iemand zal draaien. Als je alleen weet dat een tool een groen vinkje toonde, weet je eigenlijk niet wat er is bewezen. Je hebt misschien bewijs dat de bytes intact zijn maar geen idee wiens sleutel ze ondertekende. Je hebt misschien een echte ondertekenaar maar een certificaat dat jaren geleden is verlopen. De onderdelen begrijpen is wat je in staat stelt om precies te zeggen wat een geldige handtekening betekent — en, even nuttig, wat ze niet betekent.

Stel je een fraudebestendige envelop voor met een persoonlijk zegel in de flap gedrukt.

  • Het zegel is uniek voor één persoon en feitelijk onmogelijk te vervalsen. Iedereen kan het herkennen; alleen de eigenaar kan het maken. Dat is het sleutelpaar: een private sleutel die alleen jij houdt, en een publieke sleutel die iedereen kan zien.
  • Je drukt het zegel niet over het hele document. Je drukt het over een minuscule, onvervalsbare samenvatting ervan — een hash. Wijzig één byte van het document en de samenvatting verandert volledig, zodat het zegel niet meer past.
  • Ondertekenen is een handtekening over het document produceren met je private sleutel — over de hash voor RSA en ECDSA, of over de inhoud zelf voor EdDSA, die zijn eigen hashen vanbinnen doet. Verifiëren is de controle van het algoritme uitvoeren met je publieke sleutel, de handtekening en dezelfde inhoud (als hash, of rechtstreeks) — het geeft geldig of ongeldig terug. Wiskunde, niet vertrouwen, verbindt de twee.
  • Een certificaat is het deel dat zegt wiens zegel dit is. Zonder dat heb je bewezen dat een sleutel de bytes ondertekende, maar niet dat de sleutel aan iemand in het bijzonder toebehoort.
  • Een tijdstempel is het deel dat zegt wanneer. De eigen klok van een ondertekenaar is slechts een bewering; vertrouwde tijd komt van een externe autoriteit.

Begin met de hash, want al het andere staat erop. Een cryptografische hashfunctie leest een willekeurige hoeveelheid data en produceert een korte, vaste-lengte vingerafdruk — voor een PDF-handtekening doorgaans een 256-bits waarde. Twee eigenschappen maken haar nuttig: dezelfde invoer levert altijd dezelfde vingerafdruk op, en het is onhaalbaar om een andere invoer met dezelfde te vinden. Een hash is dus een getrouwe plaatsvervanger voor het document. Als twee hashes overeenkomen, komen de bytes overeen.

Nu het sleutelpaar. Een private sleutel en een publieke sleutel zijn wiskundig verbonden, maar je kunt de ene niet binnen enige praktische tijd uit de andere afleiden. Alleen de private sleutel kan een geldige handtekening produceren, en alleen de bijbehorende publieke sleutel kan die controleren. Ondertekenen maakt gebruik van die asymmetrie: de ondertekenaar past een private-sleutelbewerking toe op de invoer die het gekozen algoritme definieert — de hash van de inhoud voor RSA en ECDSA, of de inhoud rechtstreeks voor EdDSA, die intern hasht. Het resultaat is de signature value. Omdat alleen de houder van de private sleutel die kon produceren, en omdat ze gebonden is aan deze inhoud, bewijst ze twee dingen tegelijk — de houder ondertekende, en de bytes zijn sinds het ondertekenen niet verschoven.

Verificatie spiegelt die logica. De verifieerder reconstrueert dezelfde invoer — het document hashen voor RSA en ECDSA, of de inhoud rechtstreeks nemen voor EdDSA — en voert dan de verify-bewerking van het handtekeningalgoritme uit op de publieke sleutel, de signature value en die invoer. De bewerking geeft geldig of ongeldig terug — en dit is dezelfde vorm of het algoritme nu RSA, ECDSA of EdDSA is, ook al kan alleen RSA worden voorgesteld als het letterlijk “terugwinnen” van de hash. Geldig betekent intact en authentiek. Ongeldig betekent dat er iets is veranderd, of dat de verkeerde sleutel is gebruikt, en het eerlijke antwoord is ongeldig.

  1. Prepare the inputRSA and ECDSA hash the document to a short, fixed-length fingerprint; EdDSA signs the content directly and hashes it internally. Either way, any change to the bytes changes what is signed.
  2. Sign with the private keyThe signer applies a private-key operation to that input — the hash for RSA and ECDSA, the content for EdDSA. The output is the signature value; only the private-key holder could have produced it.
  3. Reconstruct the inputThe verifier independently rebuilds the same input from the content — a recomputed hash for RSA and ECDSA, the content itself for EdDSA. This is what the verify operation checks against.
  4. Verify with the public keyThe verifier runs the algorithm's verify operation on the public key, the signature value, and that input. The same shape works for RSA, ECDSA, and EdDSA.
  5. Accept or rejectThe verify operation returns valid or invalid. Valid means the bytes are intact and the private-key holder signed them. Otherwise the result is invalid — no guessing.
How a digital signature is produced and then checked, from first principles. The signer produces a signature over the content with their private key — over a hash for RSA and ECDSA, or over the content directly for EdDSA; the verifier reconstructs the same input, then runs the algorithm's verify operation on the public key, the signature, and that input. A valid result proves the bytes are intact and that the private-key holder signed them.

In een echte PDF drukt NextPDF het zegel niet over de zichtbare pagina — het drukt het over een opgegeven reeks bytes, en verpakt de handtekening als een losgekoppeld (detached) CMS-object (Spec: RFC 5652) dat in het bestand wordt geplaatst (Spec: ISO 32000-2, §12.8). Eén verfijning doet ertoe: de ondertekenaar ondertekent niet de ruwe inhoudshash rechtstreeks. Het ondertekent een kleine set signed attributes die de hash van de inhoud bevatten, zodat de tijd, het content type en de certificaat-identifier van de ondertekenaar allemaal samen worden verzegeld. Waar die bytes leven, en waarom de reeks is gevormd zoals ze is, is het onderwerp van Hoe handtekeningen in een PDF zijn ingebed.

Tot zover bewijst de wiskunde dat een sleutel deze bytes ondertekende. Ze zegt niets over wiens sleutel. Precies dat gat vult een certificaat. Een certificaat is zelf een ondertekende verklaring — van een certificeringsautoriteit — dat deze publieke sleutel aan dit benoemde subject toebehoort. Het vertrouwen erop betekent de keten volgen van het certificaat van de ondertekenaar tot aan een autoriteit die je hebt besloten te vertrouwen, en onderweg de geldigheid van elke schakel controleren (Spec: RFC 5280, §6). Zonder die keten is “ondertekend” anoniem. Mét die keten heeft “ondertekend” een naam.

Het laatste stuk is wanneer. Een handtekening kan de eigen geclaimde tijd van de ondertekenaar insluiten, maar een klok die je niet beheert, is een bewering, geen bewijs. Een tijdstempel van een Time-Stamp Authority bindt een hash van de handtekening aan een tijdstip, geattesteerd door een partij zonder belang bij het document (Spec: RFC 3161, §1). Dat is wat een handtekening betekenisvol laat blijven nadat het certificaat van de ondertekenaar is verlopen: je kunt aantonen dat de handtekening bestond terwijl het certificaat nog geldig was. De diepere behandeling staat in Tijdstempels en vertrouwde tijd.

De vormen hieronder zijn de conceptuele bewerkingen, eenvoudig opgeschreven. Het punt is geen API-aanroep — het is zien dat sign en verify spiegelbeelden zijn, en dat een gemanipuleerde byte de overeenkomst per constructie breekt.

<?php
declare(strict_types=1);
// SIGN — the holder of the private key seals the content.
// RSA and ECDSA sign a hash; EdDSA signs the content directly (hashing inside).
$signingInput = sign_input($content); // a digest for RSA/ECDSA, the content for EdDSA
$signatureValue = private_key_transform( // only the key holder can do this
privateKey: $signerPrivateKey,
input: $signingInput,
);
// VERIFY — anyone with the public key runs the algorithm's check.
$recomputedInput = sign_input($content); // verifier rebuilds the same input
$intactAndAuthentic = signature_verify( // RSA, ECDSA, EdDSA — same shape
publicKey: $signerPublicKey, // taken from the certificate
signatureValue: $signatureValue,
input: $recomputedInput, // the freshly reconstructed input
);
// true -> bytes unchanged AND signed by the private-key holder
// false -> a byte changed, or the wrong key — the honest answer is "invalid"
// The certificate answers a SEPARATE question: whose public key is this?
// The timestamp answers ANOTHER: when did this signature exist?
// "intact + authentic" alone proves neither identity nor time.

Een wijziging vervalsen die nog steeds verifieert, is computationeel onhaalbaar. De hash draagt de inhoud getrouw, dus de inhoud wijzigen wijzigt de hash, en de verify-bewerking wijst hem af — behalve door het vinden van een hash-collision, die de gekozen functie juist onpraktisch beoogt te maken.

De frequente vergissing is “geldige handtekening” lezen als “betrouwbaar document.” Het zijn niet dezelfde zin. De cryptografie bewijst dat de bytes intact zijn en dat de houder van de private sleutel ze ondertekende — niets meer. Een document ondertekend met een sleutel waar je nog nooit van hebt gehoord, geattesteerd door geen autoriteit die je herkent, kan onberispelijk “geldig” zijn en niets waard. Identiteit komt van het certificaat en zijn keten; tijd komt van een vertrouwd tijdstempel. Een groen vinkje dat dit alles stilletjes in één boolean vouwt, heeft, namens jou, besloten welke vragen ertoe deden. De onderdelen kennen is wat je in staat stelt de rest te stellen.

Deze pagina legt het idee van een digitale handtekening uit, niet de volledige validatieprocedure. De wiskunde hier bewijst integriteit en authenticiteit. Ze vertelt je op zichzelf niet of het ondertekeningscertificaat is uitgegeven aan wie je denkt, of het geldig was op het moment van ondertekenen, of dat het later is ingetrokken — dat zijn certificaatpad- en intrekkingsvragen, en een correcte validatie voert ze allemaal uit. De volledige reeks controles staat in Een handtekening correct valideren.

NextPDF bouwt de handtekeningstructuur en voert de cryptografische controles uit. Het kiest je trust anchors niet, staat niet in voor enige certificeringsautoriteit, en beslist niet over het juridische effect van een handtekening — die hangen af van je deployment, het certificaat en de jurisdictie. De engine bewijst het mechanisme; de vertrouwensbeslissingen die erbovenop liggen, zijn aan jou.

Wat de engine levert, per niveau, bouwt naar buiten vanaf dit fundament:

Digital signature: integrity, identity, and trusted time — edition availability
EditionAvailability
Core

PAdES B-B: the hash-and-sign mechanism described here, packaged as a detached CMS SignedData object, plus certificate-path validation against a trust anchor you supply.

Pro

Adds PAdES B-T — a verified RFC 3161 trusted timestamp on the signature value, so the “when” is attested rather than self-claimed.

Enterprise

Adds the long-term profiles (B-LT, B-LTA): embedded validation material and document timestamps that keep the identity and time proofs answerable for years.

  • Hash (digest) — een korte, vaste-lengte vingerafdruk van data uit een cryptografische hashfunctie; elke wijziging van de data verandert haar volledig.
  • Sleutelpaar — een verbonden private sleutel (alleen door de ondertekenaar gehouden) en publieke sleutel (vrij gedeeld); alleen de private sleutel kan ondertekenen, en alleen de bijbehorende publieke sleutel kan verifiëren.
  • Ondertekenen — de private-sleutelbewerking toepassen op de invoer die het algoritme definieert: een hash van de inhoud voor RSA en ECDSA, of de inhoud rechtstreeks voor EdDSA (die intern hasht). In een PDF is die inhoud de signed attributes, die de hash van het document bevatten. Het resultaat is de signature value.
  • Verifiëren — dezelfde invoer reconstrueren (een herberekende hash, of de inhoud rechtstreeks voor EdDSA), en dan de verify-bewerking van het algoritme uitvoeren op de publieke sleutel, de signature value en die invoer om een geldig-of-ongeldig antwoord te krijgen.
  • Signature value — de bytes die de private-sleutelbewerking produceert; waar een verifieerder tegenaan controleert met de vers gereconstrueerde algoritme-invoer (een digest voor RSA en ECDSA, de inhoud zelf voor EdDSA).
  • Certificaat — een ondertekende verklaring die een publieke sleutel aan een benoemde identiteit bindt; vertrouwd door te chainen naar een autoriteit die je accepteert (RFC 5280 §6).
  • Trust anchor — een certificeringsautoriteit die je hebt besloten te vertrouwen; de wortel van een aanvaardbare certificaatketen.
  • Tijdstempel (RFC 3161) — een ondertekend token van een Time-Stamp Authority dat een hash aan een tijdwaarde bindt, en zo vertrouwd bewijs van wanneer levert.
  • CMS SignedData — de Cryptographic Message Syntax (RFC 5652)- structuur die de signature value en het certificaat van de ondertekenaar bevat.
  • PAdES — PDF Advanced Electronic Signatures: de ETSI-profielfamilie voor PDF-ondertekening. Uitgebreid behandeld op de ondertekeningspagina’s.