Belangrijke dataformaten
Ontdek de belangrijkste cryptografie- en certificaatformaten, waaronder X.509, PKCS 7, PKCS 10, PKCS 12, ASN.1 en PEM.

X.509
X.509 is de standaard voor digitale certificaten. Er waren ooit concurrenten zoals OpenPGP, maar die worden tegenwoordig veel minder gebruikt. Al is X.509 eigenlijk niet de juiste standaard. X.509 is namelijk een ITU-T-standaard, terwijl de definities die er echt toe doen onderdeel zijn van RFC 5280, oftewel een standaard van de IETF en niet van ITU-T. Die RFC definieert het “PKI Profile for the Internet” op basis van X.509, en dat is het enige profiel dat er in de praktijk echt toe doet.
Een digitaal certificaat maakt gebruik van asymmetrische cryptografie en in het bijzonder van digitale handtekeningen. Het meest voorkomende gebruiksscenario voor digitale certificaten is vandaag serverauthenticatie. Iedereen heeft er al mee gewerkt, waarschijnlijk meestal zonder te weten dat het om een X.509-certificaat ging: elke keer dat je een HTTPS-website bezoekt, brengt de browser een TLS-verbinding met de webserver tot stand. De webserver gebruikt een X.509-certificaat om te bewijzen wie hij is. Wanneer mensen bijvoorbeeld de website van hun bank bezoeken om geld over te maken, willen ze zeker weten dat ze echt met hun bank communiceren. Aanvallers zouden zich kunnen voordoen als de banksite, het wachtwoord en de TAN van de gebruiker kunnen lezen en het geld vervolgens naar een eigen rekening kunnen overmaken. HTTPS helpt dat te voorkomen, want de aanvallers hebben het X.509-certificaat van de webserver van de bank niet. Zegt de browser dat je een bepaald domein bezoekt via een HTTPS-verbinding, dan borgt het certificaat dat je echt verbonden bent met een webserver van iemand die dat domein bezit.
Hoe doet het certificaat dat? Het certificaat bevat wat metadata, de publieke sleutel van een cryptografisch sleutelpaar en een handtekening van een certificaatautoriteit. Laten we die drie onderdelen langslopen:
Inhoud van een X.509-certificaat
Metadata
De metadata van het X.509-certificaat leggen onder meer vast voor welke periode het geldig is, waarvoor het certificaat mag worden gebruikt en aan wie het is uitgegeven. Bij een TLS-servercertificaat bevatten ze in het bijzonder het domein van de webserver. De browser vergelijkt het domein dat hij probeerde te bezoeken met dat in het certificaat. Komen ze niet overeen, dan gaat de browser niet verder maar toont hij een waarschuwing. Is het certificaat verlopen, dan toont hij ook een waarschuwing.
Vreemd genoeg toonden browsers vaak geen waarschuwing als je een HTTP-site zonder TLS bezocht, terwijl dat nog minder veilig is. Bezocht je een webserver met een ongeldig X.509-certificaat, dan kon het om een simpele configuratiefout gaan en was je misschien wel degelijk beschermd tegen aanvallers die je verbinding afluisteren, terwijl een HTTP-verbinding helemaal geen bescherming biedt.
Op dit punt is wel vooruitgang geboekt, bijvoorbeeld met certificate pinning. Maar dat is gevorderde stof, dus laten we naar de andere twee onderdelen van een X.509-certificaat kijken.
Publieke sleutel
Het certificaat bevat het publieke deel van een asymmetrisch sleutelpaar. De cryptografie stelt de webserver, of algemener de certificaathouder bij een ander gebruiksscenario, in staat om te bewijzen dat hij ook het private deel van het sleutelpaar bezit, zonder dat deel prijs te geven aan de verbindende client of aan wie dan ook. Zo kan de client er zeker van zijn dat de webserver werkelijk de eigenaar van het certificaat is en niet iemand die het gekopieerd heeft. Het certificaat zelf kopiëren is namelijk vrij eenvoudig, want de webserver stuurt er een kopie van naar iedereen die verbinding probeert te maken. De privésleutel stelen is lastig tot onmogelijk, want die verlaat de webserver nooit. Er zijn verschillende methoden om het stelen van de privésleutel nog moeilijker te maken, zoals HSM's en TPM's.
Handtekening van een certificaatautoriteit
Aan de metadata kan de client zien dat het certificaat geschikt is voor het specifieke gebruiksscenario. De publieke sleutel laat zien dat de tegenpartij werkelijk de eigenaar van het certificaat is. Maar een aanvaller zou gewoon een nieuw sleutelpaar en een nieuw certificaat kunnen maken die ook aan die twee criteria voldoen. Hoe weet een client dan dat het certificaat te vertrouwen is?
Het certificaat bevat een cryptografische handtekening van een ander sleutelpaar, dat hoort bij het certificaat van een certificaatautoriteit (CA). Dat CA-certificaat kan op dezelfde manier worden gecontroleerd en is zelf ook door een certificaat ondertekend. De client kan deze “vertrouwensketen” volgen van het zogenoemde bladcertificaat tot aan het Root CA-certificaat, dat hij herkent aan het feit dat het zelfondertekend is: de handtekening van het certificaat komt van zijn eigen sleutelpaar. Meestal zijn dat maar één of twee stappen, dus zijn er ook maar één of twee CA-certificaten bij betrokken.
CA's moeten zorgvuldig controleren of de metadata kloppen wanneer ze een certificaat uitgeven. Wil je bijvoorbeeld een TLS-servercertificaat voor je eigen domein, dan moet je de CA bewijzen dat je echt de eigenaar bent. Afhankelijk van hoe grondig die controle is, krijg je een basiscertificaat of een Extended Validation-certificaat (EV).
Elke browser en elk besturingssysteem wordt geleverd met een lijst van vooraf vastgelegde vertrouwde Root CA's. Gebruikers en beheerders kunnen extra vertrouwde Root CA's toevoegen. Sommige Root CA's worden alleen voor bepaalde doeleinden vertrouwd, andere genieten een algemener vertrouwen. De client controleert of de vertrouwensketen eindigt bij een vertrouwde Root CA. Is dat zo, zijn alle certificaten in de vertrouwensketen nog geldig en zeggen de metadata dat ze volgens hun doel worden gebruikt, dan wordt het bladcertificaat van de webserver vertrouwd en komt de verbinding tot stand.
Geldigheid van X.509-certificaten
Bij X.509-certificaten draait alles om vertrouwen dat moet worden opgebouwd. Zoals uitgelegd is één criterium voor vertrouwen dat een certificaat moet aanknopen bij een vertrouwde Root CA. Een ander is dat het zich binnen zijn geldigheidsduur bevindt. Meestal betekent dat dat het niet verlopen is, maar een certificaat kan, doorgaans door technische fouten, ook nog niet geldig zijn. Er is nog een criterium: de CA die het certificaat heeft uitgegeven, mag het niet hebben ingetrokken. Omdat dat een onderwerp op zich is, hebben we er een apart artikel over.
PKCS#7
PKCS#7 is het Zwitserse zakmes onder de cryptografische dataformaten en kan vrijwel alles bevatten: versleutelde berichten, ondertekende berichten, ondertekende en versleutelde berichten, certificaten en privésleutels
Dat is meteen het grote nadeel van dit formaat. Krijgt een applicatie of gebruiker een PKCS#7, dan is op zichzelf niet duidelijk wat ermee moet gebeuren. Een paar belangrijke gebruiksscenario's:
- S/MIME-berichten zijn in feite e-mails met PKCS#7-bodies of -bijlagen.
- SCEP-requests en -replies zijn allebei eigenlijk met PKCS#7 ondertekende berichten.
- EST-responses zijn CMS-berichten.
Codering
Veelgebruikte bestandsextensies zijn .p7b (DER-gecodeerd), .p7s (een ondertekend bericht of een berichthandtekening) en .p7m (een ondertekend en/of versleuteld bericht). De PEM-codering met het label “PKCS7” is ook gedefinieerd, maar wordt zelden gebruikt.
Tools
In Windows kun je PKCS#7-berichten openen met een dubbelklik, waarna de Crypto Shell Extensions ze voor je weergeven. Meestal kun je er echter alleen certificaten en hun privésleutels uit halen, en geen berichtinhoud.
Met tools als OpenSSL kun je deze bestanden naar andere formaten omzetten.
PKCS#10
Een certificaataanvraag (Certificate Signing Request, CSR) zoals gedefinieerd in PKCS#10 is een bestand met een beschrijving van een certificaat dat je bij een certificaatautoriteit (CA) wilt aanvragen. Het heeft een vergelijkbare structuur als een X.509-certificaat, maar de handtekening van een CA ontbreekt. In plaats daarvan bevat het de handtekening van de certificaataanvrager. Het blijft een ander formaat, dus het is niet hetzelfde als een zelfondertekend certificaat.
Het kan binair DER-gecodeerd zijn of PEM-gecodeerd met het label “CERTIFICATE REQUEST”.
PKCS#12
PKCS#12 staat ook bekend als PFX, vooral in Windows-omgevingen. Veelgebruikte bestandsextensies zijn daarom .pfx en .p12. Het bevat X.509-certificaten en vrijwel altijd de bijbehorende privésleutels, al wordt dat technisch gezien niet afgedwongen.
Data in een PKCS#12-bestand is meestal met wachtwoorden versleuteld. Vaak is alleen de privésleutel versleuteld, zodat je de certificaten zonder de wachtwoorden zou kunnen uitpakken als je applicatie dat toelaat (de meeste doen dat niet). PKCS#12 is in Windows-omgevingen de meest gebruikelijke manier om een certificaat en de bijbehorende privésleutel in een bestand op te slaan. In Linux-omgevingen zijn PEM-gecodeerde PKCS#8-bestanden gebruikelijker.
Omdat de standaard veel mogelijkheden biedt om certificaten en privésleutels in geneste “safebags” op te slaan, kennen PKCS#12-bestanden een aantal compatibiliteitsproblemen, zoals:
- Windows staat erom bekend dat het privésleutels in een PKCS#12 koppelt aan alle certificaten die uit het bestand worden gehaald, en niet alleen aan het certificaat waarvoor ze bedoeld zijn. Bevat de PKCS#12 een certificaatketen, dan kan Windows tonen dat het de privésleutel voor het CA-certificaat heeft.
- Op macOS kun je PKCS#12-bestanden niet importeren als de cryptografische algoritmen te nieuw zijn.
- Het kan nodig zijn om de certificaten in een PKCS#12-bestand te versleutelen zodat ontvangende applicaties ze kunnen uitpakken. Sommige ondersteunen echter alleen heel oude en zwakke algoritmen, wat meestal geen probleem is omdat de informatie toch openbaar is. Maar OpenSSL 3.x ondersteunt die oude en kwetsbare algoritmen niet en weigert de PKCS#12 te openen.
ASN.1 en PEM
Abstract Syntax Notation One (ASN.1) is een taal om datastructuren te beschrijven. Er zijn een aantal vooraf gedefinieerde basisdatatypen, zoals integers of sequences, en de auteur van een protocol of bestandsformaat kan daarmee vervolgens eigen datatypen definiëren.
DER-codering
De ITU-T-standaard X.680 definieert verschillende coderingen voor data die in ASN.1 is gespecificeerd. Voor X.509-gerelateerde data is DER de belangrijkste codering, omdat er maar één manier is om een type te coderen. Een hash van de binaire DER-weergave van het type heeft daardoor altijd dezelfde waarde, wat bijvoorbeeld belangrijk is bij het ondertekenen van ASN.1-gecodeerde data.
PEM-codering
Voor veel, maar niet alle X.509-gerelateerde bestandstypen kun je het bestand binair opslaan in DER-codering of er een extra PEM-codering overheen leggen. PEM gebruikt uitsluitend ASCII-tekens en kan daardoor eenvoudig via het klembord worden gekopieerd en geplakt of, enkele decennia geleden toen dat nog relevant was, per e-mail worden verstuurd.
Tools
Heb je een ASN.1-gecodeerd bestand en weet je niet welk type het is, of heb je geen applicatie die dat specifieke type aankan, dan kun je de ruwe ASN.1-structuur alsnog decoderen en bekijken wat erin staat. Op Windows kan het ingebouwde tool certutil dat met de opdracht certutil -decode.