wordt meestal in één zin uitgelegd: alleen de verzender en de ontvanger kunnen het bericht lezen. Die zin klopt en is bijna nutteloos — hij beschrijft de garantie zonder uit te leggen hoe twee toestellen die elkaar nooit hebben ontmoet, communicerend via een server die geen van beide vertrouwt, werkelijk een gedeeld geheim tot stand brengen en dat bericht na bericht, jaar na jaar veilig houden. Dit artikel opent dat op: hoe de eerste handdruk werkt wanneer de ontvanger offline is, hoe de versleutelingssleutel bij elk afzonderlijk bericht verandert, en wat E2EE bewust onbeschermd laat.

Kernpunten

  • E2EE komt tot stand via een sleutelovereenkomstprotocol, niet via een gedeeld wachtwoord — de X3DH-handdruk van het Signal-protocol laat twee toestellen een geheim afspreken, ook wanneer een van beide op dat moment offline is.
  • Zodra er een sessie bestaat, leidt het Double Ratchet-algoritme voor elk bericht een gloednieuwe sleutel af, wat forward secrecy oplevert (eerdere berichten blijven veilig als een sleutel lekt) en post-compromise security (de sessie geneest zichzelf na een inbraak).
  • Groepsgesprekken kunnen dezelfde handdruk niet zomaar paarsgewijs op schaal draaien — sender keys ruilen een beetje forward secrecy in om elk bericht één keer te versleutelen in plaats van één keer per ontvanger.
  • E2EE beschermt inhoud, geen metadata — wie met wie sprak, wanneer, en hoe vaak is in de meeste implementaties nog steeds zichtbaar voor de server.
  • Het lastigste onopgeloste probleem in E2EE in productie is geen cryptografie, het is sleutelverificatie: bewijzen dat de publieke sleutel die je ontving werkelijk van je contact is en niet van een aanvaller ertussen.

Wat "tot stand gebracht" werkelijk betekent

Symmetrische versleuteling zoals AES vereist dat beide kanten al dezelfde sleutel hebben. Dat werkt prima zodra er een gedeeld geheim bestaat, maar het verklaart niet hoe dat geheim er kwam — je kunt de sleutel niet over hetzelfde kanaal sturen dat je probeert te beschermen, en je kunt niet verwachten dat de apps van twee vreemden vooraf iets hebben gedeeld. E2EE tot stand brengen betekent dat bootstrapprobleem oplossen: een gedeeld geheim afleiden tussen twee toestellen met alleen publieke informatie, over een netwerk dat wordt beheerd door een partij die geen van beide toestellen vertrouwt.

Het mechanisme dat vrijwel elke moderne veilige berichtenapp gebruikt is het Signal-protocol, ontworpen door Trevor Perrin en Moxie Marlinspike. Het draait Signal zelf, WhatsApp, en de versleutelde laag van Google Messages (RCS). De handdruk heet X3DH — Extended Triple Diffie-Hellman — en die lost een probleem op dat een gewone Diffie-Hellman-uitwisseling niet kan: een sessie starten met iemand die op dit moment niet online is.

De X3DH-handdruk: een geheim afspreken met iemand die offline is

Een telefoongesprek vraagt dat beide partijen tegelijk opnemen. Een tekstbericht niet — je stuurt het, en het wacht. Berichtenapps moeten versleuteling opbouwen met diezelfde asynchrone eigenschap: Alice moet een versleuteld gesprek met Bob kunnen beginnen ook als Bobs telefoon uitstaat.

X3DH bereikt dat door elke gebruiker vooraf een kleine bundel publieke sleutels naar de server te laten publiceren, voordat ze nodig zijn:

  1. Identiteitssleutel (IK) — een langlevend sleutelpaar dat het toestel identificeert. Het verandert zelden en is wat verificatie van het veiligheidsnummer uiteindelijk controleert.
  2. Ondertekende prekey (SPK) — een sleutelpaar met een middellange levensduur, periodiek gewisseld (de X3DH-specificatie stelt een interval in de orde van weken tot een maand voor), ondertekend met de identiteitssleutel zodat een ontvanger kan verifiëren dat hij werkelijk van dat toestel komt.
  3. Eenmalige prekeys (OPK) — een reeks sleutelparen voor eenmalig gebruik. De server geeft er per nieuwe binnenkomende sessie één uit en gooit hem daarna weg, en elk toestel uploadt periodiek nieuwe om de voorraad aan te vullen.

Wil Alice Bob voor het eerst een bericht sturen, dan haalt ze een van deze bundels bij de server op (nooit een private sleutel — alleen de publieke helften). Vervolgens berekent ze drie of vier afzonderlijke Diffie-Hellman-uitwisselingen tussen combinaties van haar eigen sleutels en die van Bob:

  • DH1 = haar identiteitssleutel met Bobs ondertekende prekey
  • DH2 = haar efemere (vers gegenereerde, eenmalige) sleutel met Bobs identiteitssleutel
  • DH3 = haar efemere sleutel met Bobs ondertekende prekey
  • DH4 = haar efemere sleutel met Bobs eenmalige prekey, als die beschikbaar was

Ze plakt de resultaten aan elkaar en haalt ze door een sleutelafleidingsfunctie (HKDF) om één gedeeld geheim te produceren. Bob heeft, zodra hij online komt, alle private helften die nodig zijn om diezelfde waarde zelf te berekenen — DH is commutatief op precies de manier die dit laat werken. Geen van beide partijen verstuurt ooit het geheim zelf; ze berekenen elk onafhankelijk hetzelfde getal uit een mengsel van langlevende, middellange en eenmalige sleutels.

Waarom vier afzonderlijke DH-berekeningen in plaats van één? Elke levert een specifieke eigenschap op:

  • DH1 en DH2 binden de sessie aan de langlevende identiteiten van beide partijen — dat is wat de uitwisseling geauthenticeerd maakt en niet alleen geheim.
  • DH3 (en DH4 wanneer er een eenmalige sleutel beschikbaar was) voegt vers, wegwerpbaar materiaal toe, zodat wanneer een langlevende identiteitssleutel later wordt gecompromitteerd, eerder onderhandelde sessies niet opnieuw te berekenen zijn. Dat is het begin van forward secrecy, nog voordat de ratchet begint.
  • De eenmalige prekey verdedigt specifiek tegen een server die liegt over de ondertekende prekey — elke OPK precies één keer gebruiken beperkt hoeveel een kwaadwillende of gecompromitteerde server kan herhalen.

De uitkomst van X3DH is één gedeeld geheim van 256 bits. Dat ene geheim voor elk bericht gedurende het hele gesprek gebruiken zou precies het probleem zijn waarmee dit artikel opende: één gelekte sleutel legt alles bloot. Dat geheim is dan ook niet het einde van het verhaal — het is het zaad voor de Double Ratchet.

De Double Ratchet: een nieuwe sleutel voor elk bericht

Een ratel draait mechanisch maar één kant op. Het Double Ratchet-algoritme leent die naam bewust: de versleutelingsstaat beweegt alleen vooruit, en er is geen manier om terug te draaien en uit een latere sleutel een eerdere te herleiden.

Het combineert twee ratels die samen draaien:

De symmetrische sleutelratel. Elke kant houdt een "ketensleutel" bij. Elke keer dat er een bericht wordt verstuurd, gaat de huidige ketensleutel door een hashfunctie (HMAC) die twee uitkomsten oplevert: een berichtsleutel, waarmee dat ene bericht wordt versleuteld en die daarna wordt weggegooid, en een nieuwe ketensleutel, die de oude vervangt. Berichtsleutels worden nooit hergebruikt en zijn niet omgekeerd uit elkaar af te leiden — een hashfunctie loopt alleen vooruit. Neemt een aanvaller cijfertekst op en steelt hij later een ketensleutel, dan kan hij elk bericht ontsleutelen dat na dat punt is verstuurd, maar niets ervoor.

De Diffie-Hellman-ratel. De symmetrische ratel alleen heeft nog een zwakte: een gestolen ketensleutel compromitteert vanaf dat moment alles, onbeperkt. Om dat te verhelpen genereert elke kant, telkens wanneer het gesprek "keert" — grofweg elke keer dat de andere partij antwoordt — een vers efemeer DH-sleutelpaar, voert een nieuwe Diffie-Hellman-uitwisseling uit met de nieuwste publieke sleutel van de tegenpartij, en mengt het resultaat in de ketensleutel. Zo komt er op een regelmatige cadans nieuwe, onvoorspelbare entropie in het systeem die een aanvaller niet kan voorspellen of vooraf berekenen.

De combinatie geeft twee verschillende garanties die vaak op één hoop worden gegooid maar niet hetzelfde zijn:

  • Forward secrecy — de sleutel van vandaag compromitteren legt de berichten van gisteren niet bloot. Geleverd door de symmetrische ratel: oude ketensleutels zijn al weg, vooruit gehasht en weggegooid.
  • Post-compromise security (de Double Ratchet-specificatie noemt dit "break-in recovery"; informeel ook wel zelfherstel) — de sleutel van vandaag compromitteren legt ook de berichten van morgen niet bloot, omdat de volgende stap van de DH-ratel nieuwe willekeur injecteert die de aanvaller nooit zag. Geleverd door de DH-ratel.

Samen betekenen ze dat één inbraak op één moment — een gestolen toestel, een afgedwongen sleutel — een straal heeft en geen blijvende breuk. Het gesprek geneest zichzelf binnen een bericht of twee met verse DH-uitwisselingen, en dat is een wezenlijk ander beveiligingsmodel dan "de sleutel is gecompromitteerd, dus het gesprek is voorgoed gecompromitteerd".

Groepsberichten: waarom het paarsgewijze protocol niet schaalt

X3DH plus de Double Ratchet beschrijft een sessie tussen twee mensen. Een groep van 200 mensen heeft geen "sessie" — die heeft tot 200×199 mogelijke paarsgewijze sessies, en elk bericht één keer per ontvanger versleutelen zou 200 afzonderlijke versleutelingen (en 200 keer de bandbreedte) betekenen voor één tekstbericht.

Het antwoord van Signal is sender keys. In plaats van paarsgewijze ratels tussen elk lid, genereert elke deelnemer één symmetrische "sender key" en verspreidt die individueel naar elk ander groepslid, over de al bestaande paarsgewijze Double Ratchet-sessies (die eerste verspreiding is het dure deel, en gebeurt één keer per wijziging in het ledenbestand). Daarna versleutelt de verzender een groepsbericht precies één keer met zijn sender key, en kan elk lid dat die sleutel heeft ontvangen het rechtstreeks ontsleutelen — geen versleuteling per ontvanger op het hete pad.

Dat levert enorme prestatiewinst op ten koste van enkele ratel-eigenschappen: een sender key rolt niet per bericht vooruit zoals een paarsgewijze Double Ratchet-keten dat doet, dus hij biedt binnen zijn eigen levensduur zwakkere forward secrecy, en hij moet uitdrukkelijk worden gewisseld zodra het ledenbestand verandert — vertrekt iemand uit een groep, dan moet elk overgebleven lid een nieuwe sender key genereren en verspreiden, anders zou de kopie van de vertrokken persoon toekomstige berichten nog kunnen ontsleutelen. Precies daarom is iemand uit een grote groep met veel verloop verwijderen meetbaar duurder dan hem een gewoon bericht sturen — die wissel doet echt cryptografisch werk, geen database-update.

Het probleem dat cryptografie alleen niet oplost: sleutels verifiëren

Alles hierboven gaat ervan uit dat Alice werkelijk Bobs publieke sleutels van de server kreeg, en niet die van een aanvaller. Geeft de server (of iemand die zich als de server kan voordoen) Alice in plaats daarvan een sleutelbundel die een aanvaller beheerst, dan draait X3DH feilloos en produceert het een volstrekt geldig gedeeld geheim — met de verkeerde persoon. Dat is een klassieke man-in-the-middle-aanval, en geen enkele hoeveelheid sleutelafleiding lost dat op, omdat de wiskunde nooit controleert wiens sleutel ze ontving.

De maatregel is verificatie buiten het kanaal om: Signal en WhatsApp tonen een veiligheidsnummer (een vingerafdruk afgeleid uit de identiteitssleutels van beide partijen) die gebruikers persoonlijk, via de stem of met een QR-code kunnen vergelijken. Komen de nummers overeen, dan zijn de identiteitssleutels echt en onderschept niemand de uitwisseling. Die stap is optioneel, de meeste gebruikers doen hem nooit, en dat gat — niet de cryptografie — is waar de realistische aanvallen op E2EE-berichtenapps werkelijk plaatsvinden: een gecompromitteerde of onder druk gezette sleutelserver, geen gebroken versleuteling.

Wat het je oplevert, en wat niet

Voordelen:

  • Vertrouwelijkheid overleeft een gecompromitteerde server. Doordat de server alleen cijfertekst bewaart (en, in X3DH, publieke sleutels), kan een gehackte database, een gevorderde back-up of een malafide medewerker de inhoud van berichten niet blootleggen — er is niets leesbaars om te overhandigen.
  • Forward secrecy beperkt de schade van sleuteldiefstal. Een gestolen toestel of een gecompromitteerde langlevende sleutel ontgrendelt niet met terugwerkende kracht de hele berichtgeschiedenis van een gebruiker.
  • Post-compromise security betekent dat het systeem herstelt. Anders dan bij één statische sleutel repareert een gecompromitteerde Double Ratchet-sessie zichzelf binnen een paar berichten.
  • Groepsberichten schalen zonder versleuteling per ontvanger, dankzij sender keys — bruikbare prestaties bij aantallen waar paarsgewijze versleuteling zou bezwijken.

Nadelen:

  • Metadata blijft onaangeroerd. De server ziet nog steeds wie wie berichten stuurt, hoe vaak, vanaf welk IP-adres, en hoe lang — onderzoek laat consequent zien dat metadata alleen al gevoelige patronen in relaties en gedrag blootlegt, soms betrouwbaarder dan de inhoud zou doen.
  • Een gecompromitteerd eindpunt omzeilt alles. E2EE beschermt gegevens onderweg en in rust op de server — niet op een toestel dat al door malware of fysieke toegang is gecompromitteerd. Ontsleutelde berichten zijn per definitie leesbaar op het toestel dat ze ontsleutelde.
  • Sleutelverificatie is handwerk en wordt meestal overgeslagen. Het protocol is zo sterk als zijn zwakste schakel, en voor de meeste gebruikers is die schakel "ik heb het veiligheidsnummer nooit gecontroleerd".
  • Achteraf inbouwen is duur. Functies die uitgaan van zicht aan de serverkant — zoeken, spamdetectie, linkvoorbeelden, contentmoderatie, back-ups — moeten allemaal opnieuw worden gebouwd of ontworpen rond cijfertekst die de server niet kan lezen. Precies die migratie documenteerde het engineeringteam van Meta voor Messenger, en het is ook waarom het terugdraaien van E2EE uit de directe berichten van Instagram in 2026 een product- en regelgevingsbesluit was en geen cryptografisch — het mechanisme dat dit artikel beschrijft was al gebouwd en werkte. Die terugdraai, en hoe E2EE naast AES, TLS en post-quantumcryptografie in een bredere beveiligingsarchitectuur past, behandelen we in Versleuteling uitgelegd.
  • Wijzigingen in het ledenbestand kosten echt cryptografisch werk. Een lid verwijderen vraagt om sender keys wisselen en opnieuw verspreiden, niet om een vinkje in de toegangsrechten omzetten.

Ervoor ontwerpen, niet erop schroeven

De terugkerende les uit elk E2EE-systeem in productie — Signal, WhatsApp, iMessage — is dat juist de delen van een berichtenproduct die niets met cryptografie te maken lijken te hebben (zoeken, voorbeelden in meldingen, spamfilters, back-ups, synchronisatie over meerdere toestellen) bepalen of E2EE haalbaar is. Een sleuteluitwisselingsprotocol en een ratel zijn inmiddels goed begrepen, publiek beoordeelde bouwstenen; het lastige engineeringwerk zit overal waar de server vroeger zicht had en nu niet meer.

Bouw of beoordeel je een product dat gevoelige gebruikersgegevens verwerkt — medische dossiers, financiële communicatie, juridische correspondentie — dan hoort het ontwerpbesluit over end-to-end-versleuteling in de architectuurfase te vallen, niet als aanbouw achteraf. Precies dat soort gat zoeken we in een audit van AI-code: plekken waar een functie stilzwijgend uitgaat van toegang aan de serverkant tot leesbare tekst die het beveiligingsmodel beloofde nooit te laten bestaan. Wil je een tweede paar ogen op hoe versleuteling in de architectuur van je applicatie past, neem dan contact op.

Bronnen