Mensen beschrijven een VPN als „iets dat publieke-sleutelversleuteling gebruikt“ en stellen zich dan voor dat elk pakket met het servercertificaat op slot zit. Dat beeld is onjuist op een manier die ertoe doet wanneer je een configuratiebestand of een pakketopname leest. De publieke-sleutelhelft van een VPN gaat over bewijzen wie de peer is en het eens worden over geheim materiaal; de symmetrische helft is wat het verkeer werkelijk beschermt, pakket na pakket, gedurende de hele sessie.

Beide helften hebben een andere levensduur, andere faalwijzen en andere dingen die veilig gepubliceerd kunnen worden. Zodra je ze scheidt, houden vragen als „is RSA 2048 zwakker dan AES-128“ op met verwarren, omdat ze nooit vergelijkbaar waren.

Drie bewerkingen die door elkaar lopen

Publieke-sleutelcryptografie is een paraplu over minstens drie verschillende bewerkingen. Een handtekening bewijst dat de houder van een privésleutel een bepaald bericht heeft goedgekeurd. Sleutelovereenkomst laat twee peers een gedeeld geheim afleiden uit waarden die ze openbaar uitwisselen. Publieke-sleutelversleuteling verbergt gegevens onder iemands publieke sleutel, zodat alleen de privésleutel ze kan openen.

VPN-handshakes gebruiken meestal de eerste twee. Een certificaat is geen versleutelingssleutel; het is een ondertekende verklaring die een naam aan een publieke sleutel bindt en de andere kant laat beslissen of die de zojuist ontvangen sleutel vertrouwt. De sleutelopzet van TLS 1.3 is bijvoorbeeld gebaseerd op (EC)DHE-sleutelovereenkomst plus certificaathandtekeningen, niet op het versleutelen van de sessie met de publieke sleutel van de server.

Wat de handshake werkelijk oplevert

In een moderne handshake maakt elke kant een efemeer sleutelpaar, wisselt de publieke helften uit en berekent een gedeeld geheim dat nooit over de draad gaat. Dat geheim gaat vervolgens door een sleutelafleidingsfunctie om aparte sleutels per richting te maken, plus de nonce en het IV-materiaal dat de recordlaag nodig heeft. WireGuard doet dit met zijn op Noise gebaseerde constructie; TLS 1.3 doet het met HKDF over het handshake-transcript.

De langetermijncredential — certificaat en privésleutel, of een statische WireGuard-sleutel — authenticeert die uitwisseling. Die ondertekent of mengt zich in het transcript, zodat een buitenstaander de handshake niet namens de peer kan voltooien. Daarna verricht de credential geen werk per pakket. Als dat wel zo was, zou elk pakket een privésleutelbewerking vereisen, en een drukke tunnel zou beperkt worden door de traagste bewerking in de stack.

Twee neveneffecten volgen. Ten eerste zijn sessiesleutels elke keer vers, dus een aanvaller die later de langetermijnsleutel steelt, kan eerder opgenomen sessies niet ontsleutelen, mits de overeenkomst efemeer was. Ten tweede compromitteert een uitgelekte sessiesleutel één sessie, niet de identiteit.

Waarom grote datavolumes symmetrische sleutels gebruiken

Symmetrische cijfers verwerken volume goed: AES-GCM of ChaCha20-Poly1305 verwerken elk pakket met een sleutel die al in het geheugen staat, authenticeren de kop en verhogen een teller. De ontvangende kant controleert de nonce en de authenticatietag en gooit alles weg dat faalt of zich herhaalt. Dat is goedkoop genoeg om op lijnsnelheid te draaien op gewone hardware, en dezelfde constructie geeft vertrouwelijkheid en integriteit in één doorgang.

De constructie is ook de plek waar de meeste implementatiefouten leven. Een herhaalde nonce in GCM breekt vertrouwelijkheid en authenticiteit tegelijk, dus protocollen leiden sleutels per richting af en houden een expliciete teller of epoch bij. Als je een pakketopname leest en de lengte van de ciphertext komt overeen met de plaintext plus een vaste overhead, dan werkt de symmetrische laag, niet een publieke-sleutelbewerking per pakket.

Levensduur, sleutelvernieuwing en voorwaartse geheimhouding

Sessiesleutels zijn bedoeld om te verlopen. TLS 1.3 staat een KeyUpdate-bericht toe om de verkeerssleutels te rollen; WireGuard vernieuwt een sessie na een ingestelde tijd of berichtaantal en houdt de oude kort vast voor pakketten onderweg. OpenVPN onderhandelt volgens schema opnieuw over de sleutels van zijn datakanaal, waarbij reneg-sec het interval bepaalt.

Geen van die rotaties is hetzelfde als een certificaat vernieuwen. Een certificaat kan een jaar geldig zijn terwijl sessiesleutels elke paar minuten veranderen, en een certificaat kan worden vervangen zonder de sleutels van de lopende tunnel aan te raken. Als je een afloop plant, vraag dan welk object je roteert; het antwoord bepaalt of clients opnieuw verbinden of alleen sleutels vernieuwen.

Configuratie en diagnostiek lezen zonder objecten te mengen

In de praktijk kies je een volledig protocol en de ondersteunde primitieven, je stelt niet je eigen samen. De --tls-crypt-sleutel van OpenVPN beschermt het controlekanaal; het datakanaal gebruikt onderhandelde symmetrische cijfers. De PrivateKey- en PublicKey-regels van WireGuard zijn identiteitsmateriaal, terwijl de transportsleutels intern worden afgeleid. Die velden als hetzelfde soort geheim lezen leidt tot fouten zoals een publieke sleutel plakken waar een privésleutel hoort.

Houd publiek materiaal gescheiden van privé. Een certificaat, een publieke WireGuard-sleutel en een vingerafdruk zijn veilig om in een ticket te delen. Een privésleutel, een vooraf gedeelde sleutel en een geëxporteerde sessiesleutel niet. Vergelijk bij sterkte binnen één type: een elliptische-curve-identificatie, een RSA-modulusgrootte en een AES-sleutelgrootte meten verschillende dingen onder verschillende aannames. De TLS 1.3-specificatie is een nuttige referentie voor hoe de twee lagen in elkaar passen, ook als je tunnel geen TLS is.

Gerelateerde artikelen