3 Cryptografie
Na dit hoofdstuk kan je:
- Het principe van Kerckhoffs uitleggen en motiveren waarom publiek getest crypto veiliger is dan security through obscurity.
- Het verschil tussen symmetrische en asymmetrische encryptie duiden (snelheid ↔︎ sleuteldistributie) en aangeven wanneer je welke inzet.
- Voor een gegeven blockcipher-mode (ECB, CBC, CTR) uitleggen waarom ECB onveilig is en de rol van IV/nonce beschrijven.
- Hashing, digitale handtekeningen en certificaten correct situeren binnen integrity, authenticiteit en non-repudiation.
- De werking van HTTPS/TLS beschrijven als samenspel van asymmetrische + symmetrische crypto, hashing en PKI — en de impact van een MITM-aanval (mitmproxy) inschatten.
In dit hoofdstuk duiken we de boeiende wereld van de cryptografie in: het versleutelen van informatie zodat enkel zender en ontvanger het bericht kunnen lezen.
3.1 Encryptie en decryptie
Herinner je dat we in het vorige hoofdstuk de termen CIA aanhaalden en de McCumber kubus? Een grote pijler van CIA, confidentiality, wordt opgelost met behulp van encryptie, namelijk het versleutelen van onze data met behulp van een geheime sleutel. Door deze te versleutelen wordt deze onleesbaar voor personen die de geheime sleutel niet hebben (en bijgevolg niet geautoriseerd zijn om de data te mogen lezen). De moeilijkheid van een goed cryptografisch systeem is dat de data op een zodanige manier moet versleuteld worden dat het quasi onmogelijk is om zonder sleutel de originele data terug te vinden. We spreken hierbij over de originele data als de plaintext en de geëncrypteerde data als ciphertext. De ontvanger van een ciphertext moet deze, als hij de juiste sleutel heeft, terug kunnen omzetten naar de originele plaintext.
Er zijn al veel encryptie algoritmes de revue gepasseerd doorheen de geschiedenis van de mens. Al van in de tijd van de Romeinen werd er aan cryptografie gedaan. Mensen hebben altijd gevoelige data gehad waar vertrouwelijk mee moest om gesprongen worden. Naarmate de cryptanalyse (dat is het proberen ontcijferen van een ciphertext zonder dat je de geheime sleutel hebt) evolueerde, moesten ook de cryptografische algoritmes verbeteren. Ook hier zien we weer diezelfde wedloop tussen digitale stropers en cyberboswachters. Hoe sterker onze computers worden (met dank aan de wet van Moore), hoe krachtiger onze algoritmes moeten worden. De eenvoudigste vorm van cryptanalyse, bruteforcing, is rechtstreeks afhankelijk van de snelheid van de computer. Hoe meer sleutels per seconde een computer kan testen, hoe sneller de originele sleutel kan gevonden worden.
De volledige geschiedenis van de cryptografie hier vertellen zou ongeveer 1200 pagina’s vereisen. Het briljante boek “The Codebreakers” van David Kahn is een aanrader voor eenieder die meer willen weten over deze boeiende geschiedenis. Laat de 1200 pagina’s je niet afschrikken, het boek leest als een echte thriller.
Alle bestaande cryptografische systemen kunnen op verschillende manieren gekarakteriseerd worden (bron Network Security Essentials, door William Stallings):
- De acties die op de data worden uitgevoerd om deze te encrypteren:
- Substitutie: een teken door een ander teken vervangen.
- Transpositie: een teken op een andere plek in de tekst zetten.
- Product: een combinatie van meerdere substituties en transposities.
- Het aantal sleutels dat nodig zijn:
- 1 sleutel, ook wel “private encryption” genoemd.
- 2 sleutels, ook wel “public encryption” genoemd.
- De manier waarop de data wordt verwerkt:
- Als een blok data, blok per blok.
- Als een stream, teken per teken.
3.2 Kerckhoffs principe
We gaan zo meteen bekijken hoe encryptie effectief gebeurt, maar we willen al even een mythe onderuit halen. Binnen encryptie heb je de principes van Kerckhoff, zes regels die in de 19e eeuw werden vastgelegd waaraan encryptie-algoritmes moeten voldoen om als veilig beschouwd te worden. Sommige principes zijn, onder ander door onze steeds krachtigere computers, niet meer relevant, maar één principe blijft ongelooflijk belangrijk: “Het kennen van het gebruikte encryptie-algoritme door de tegenstander is geen probleem, het is enkel de geheime sleutel die ten allen tijde uit de handen van de tegenstander moet blijven.”
Dit ogenschijnlijk eenvoudige zinnetje betekent heel veel: je sleutel (of wachtwoord) is wat je het beste moet beschermen. Zonder kennis van de sleutel zou iemand nooit toegang mogen krijgen tot versleutelde data, ongeacht dat geweten is met welk systeem de data werd vercijferd.
We zagen reeds dat Security through obscurity een dubbel snijdend zwaard binnen de security wereld is. Enerzijds is het niet aangeraden om met veel tamtam aan te kondigen hoe jij je data beveiligt. Anderzijds geeft het je mogelijk een vals gevoel van veiligheid (snake’s oil) daar het geheimhouden van je algoritme en systemen geen garantie is dat deze ook effectief veilig zijn. In de 21e eeuw zijn de meest gebruikte encryptie-algoritmes publiek gekende algoritmes die door duizenden experts aan de tand zijn gevoeld. De kans dat er dus (bewuste) fouten in dergelijke standaarden zitten, is véél kleiner dan wanneer je met een zogenaamd proprietary systeem werkt waarvan de werking angstvallig geheim wordt gehouden.
Finaal draait alles op het geheimhouden van je sleutel, iets dat we telkens weer in dit boek zullen herhalen!
3.2.1 Opletten met reclame
Let op met encryptiesystemen die zichzelf verkopen met zinnen zoals “10 jaar nodig op een gewone laptop om alle sleutels te testen”. Dit zou kunnen doen vermoeden dat je dus voor minstens tien jaar goed zit (we gaan er even vanuit dat de gemiddelde cryptanalist maar toegang heeft tot één laptop, wat uiteraard in de echte wereld niet zo is). De gemiddelde tijd van voorgaande systeem om te bruteforcen is echter vijf jaar, de helft.
Stel dat je een sleutel hebt die bestaat uit 8 karakters. Een karakter is een letter van a tot z (geen onderscheid tussen hoofd- en kleine letters en geen getallen of speciale tekens). Er zijn \(26^8\) mogelijke sleutels (we gaan ervan uit dat de sleutel exact 8 karakters moet bevatten). Een computer kan één miljoen sleutels per seconde testen. De duur om alle mogelijke sleutels te testen is dus \(\frac{(26^8)}{1 000 000}\), oftewel 208 827 seconden, pakweg 58 uur. Intuïtief zou je kunnen denken dat je dus meer dan twee dagen “veilig” zit, wat niet zo is. De kans dat de eerste sleutel die je test reeds de juiste is, is even groot als dat het de laatste sleutel is. Kortom, gemiddeld gezien zal de sleutel in de helft van de maximum tijd gevonden worden, oftewel 29 uur.
Zouden we de lengte van de sleutel met één karakter verhogen, naar 9, dan stijgt de maximale duur naar pakweg 1500 uur, oftewel 62 dagen. Gemiddeld gezien vinden we de sleutel dus na ongeveer 750 uur (ruim 31 dagen). Eén karakter extra heeft wel degelijk een gigantische impact op de veiligheid van een sleutel!
3.3 De eerste algoritmes
Het doel van ieder encryptie-algoritme is om data zodanig te versleutelen zodat enkel eigenaars van de gebruikte sleutel de originele tekst kunnen terugvinden. We vertelden net dat encryptie-algoritmes kunnen onderverdeeld worden volgens de actie die ze uitvoeren: substitutie, transpositie of een combinatie. We tonen van iedere variant nu een historisch voorbeeld.
Volgende tool, speciaal gemaakt om crypto te leren, is een erg handig iets om de verschillende cryptografische systemen te visualiseren én testen: link
3.3.1 Substitutie: Caesar encryptie
De Caesar encryptie (naar Julius Caesar) bestaat uit een eenvoudig substitutie algoritme. De sleutel is een getal tussen 1 en 25 en geeft aan door welk element uit het alfabet een teken wordt aangepast, als volgt:
- Ieder element wordt voorgesteld als een cijfer. A krijgt de waarde 0, B wordt 1,… Z wordt 25. (We tellen vanaf 0, zodat we straks netjes met de modulo-operator kunnen werken.)
- Als de sleutel het getal 3 is, dan zal nu iedere letter A in de tekst vervangen worden door het teken 0+3, dus D. Iedere B wordt een E, enzovoort.
- Indien er een “overflow” is achteraan komen we uiteraard terug naar voor in het alfabet. Iedere Z wordt dus een C, iedere Y een B, enzovoort.
Het Caesarcipher wordt ook wel kortweg Rot genoemd, naar het woord rotatie. Een cijfer erachter geeft dan aan welk de te gebruiken sleutel is. Rot4 wil dus zeggen dat alle elementen vier plaatsen opgeschoven moeten worden. Merk op dat Rot13 (ook wel Caesaralfabet genoemd) een speciale sleutel is. Als je namelijk twee maal na elkaar Rot13 toepast op een tekst (eerst op de plaintext, dan op de resulterende ciphertext) dan verkrijgt men terug de originele tekst.
Een mooie fysieke manier om Caesar te visualiseren is met een cipher wheel (of Caesar-wiel): twee concentrische schijven die allebei het alfabet langs de rand hebben staan. Door de binnenste schijf een aantal plaatsen te draaien (afhankelijk van je sleutel), kan je voor iedere letter op de buitenste schijf meteen aflezen welke letter eronder staat. Geen pen en papier nodig — gewoon draaien en aflezen. Historisch werden dergelijke wielen letterlijk gebruikt door legers en spionnen om snel in en uit geheimschrift te gaan.
Uiteraard kan iedere weldenkende mens in de 21e eeuw een Caesar encryptie bruteforcen. Het aantal mogelijke sleutels beperkt zich tot 25 mogelijkheden (sleutels 0, 26, etc. zullen resulteren in géén encryptie: je plaintext en ciphertext zullen identiek zijn) en je kan dit dus snel testen.
Door frequentieanalyse op de ciphertext toe te passen kan men ook de plaintext terugvinden zonder te moeten bruteforcen. Indien de plaintext een tekst in, bijvoorbeeld, het Nederlands is, dan kunnen we gebruik maken van de statistische eigenschappen van een taal. Zo weten we dat bepaalde letters in een standaard Nederlandstalige tekst meer of minder vaak voorkomen. De letter e komt bijvoorbeeld veel vaker voor dan de v. Daar iedere letter in de encryptie door een andere wordt vervangen, is het dus voldoende om te ontdekken (a.d.h.v. frequentieanalyse) welke letter(s) het meest of minst voorkomen om je zo een vermoeden te geven van de originele letter.
Dit verklaart ook waarom je best je te encrypteren berichten zo kort mogelijk houdt. Hoe minder tekens, hoe minder frequentieanalyse zal werken. Een andere veelvoorkomende fout (in klassiekere encryptie) was dat de verzender bijvoorbeeld voorspelbare tekst ging encrypteren. Als je weet dat de verzender altijd begint met “Geachte” in z’n berichten, dan is de kans groot dat de eerste 7 tekens in de ciphertext deze plaintext voorstellen.
Het principe van Caesar encryptie, de substitutie, blijft echter overeind staan en zal je nog zien terugkomen in de komende algoritmes.
3.3.1.1 Over de modulo operator
De modulo operator (%) is nuttig bij substitutie-algoritmes zoals bij Caesar encryptie. De modulo operator geeft de rest weer wanneer we de linkse door de rechtse operator zouden delen. 19%5 geeft dus 4 als resultaat.
Je kan de operator gebruiken om snel te weten wat de waarde van een teken wordt bij Caesar-encryptie als volgt:
(teken + sleutel) % alfabetLengte => nieuw teken
De alfabetLengte is 26 bij Caesar-encryptie, namelijk alle letters van A tot en met Z.
Als je dus een sleutel hebt met waarde 7 en je wilt weten wat de waarde van Y (element 24, daar we vanaf 0 tellen) wordt dan schrijf je:
(24 + 7) % 26 => 5
Dit zal dus 5 worden, oftewel een F.
3.3.2 Vigenère: een slimmere substitutie
De grote zwakte van Caesar is dat iedere letter altijd op dezelfde manier wordt vervangen: in een tekst vercijferd met sleutel 3 wordt iedere e een h. Net daarom werkt frequentieanalyse zo goed.
Het Vigenère-cipher, vernoemd naar de 16e-eeuwse Fransman Blaise de Vigenère, pakt dit aan met een verrassend eenvoudige truc: in plaats van één vaste shift gebruik je een sleutelwoord dat je herhaalt over de plaintext. Iedere letter van het sleutelwoord bepaalt hoeveel de bijhorende plaintext-letter moet opschuiven. Je kan Vigenère dus zien als een rij Caesar-ciphers na elkaar, elk met een eigen shift.
Stel dat onze sleutel COUNTON is en de plaintext vigenerecipher. We herhalen het sleutelwoord tot het even lang is als de plaintext:
Sleutel: C O U N T O N C O U N T O N
Plaintext: v i g e n e r e c i p h e r
Ciphertext: X W A R G S E G Q C C A S E
De eerste v gecombineerd met sleutel-letter C levert X op (shift 2). De volgende i met O geeft W. En zo verder. Merk op dat de vier e’s in de plaintext telkens door een andere letter worden vervangen (respectievelijk R, S, G en S), afhankelijk van welke sleutelletter er op dat moment boven staat.
In de praktijk gebruikte men een tabula recta - een tabel met alle 26 Caesar-alfabetten onder elkaar - om snel de juiste substitutie af te lezen. De rij kies je op basis van de sleutelletter, de kolom op basis van de plaintext-letter.
En dát is de kracht van Vigenère: eenvoudige frequentieanalyse werkt niet meer. Letters die in de plaintext veel voorkomen, zijn niet langer letters die in de ciphertext veel voorkomen.
Vigenère heette eeuwenlang le chiffre indéchiffrable — “het onontcijferbare cipher”. Pas in de 19e eeuw werd het systematisch gekraakt door Friedrich Kasiski: eens je de sleutellengte kan achterhalen (via het tellen van herhalingen in de ciphertext), herleidt Vigenère zich tot meerdere parallelle Caesar-ciphers die je elk afzonderlijk met frequentieanalyse kan aanvallen.
Het principe van Vigenère - variatie inbrengen door een sleutel die zelf varieert - zie je nog steeds terug in moderne algoritmes. De round keys in DES en AES die we verderop behandelen, zijn directe nazaten van dit idee.
3.3.3 Transpositie: scytale encryptie
Bij transpositie-algoritmen gaan we de positie van de karakters veranderen. De sleutel kan hierbij bepalen op welke manier dit moet gebeuren. De Oude Grieken gebruikten een zogenaamde scytale om aan transpositie-encryptie te doen. Een scytale was een lange stok bestaande uit drie of meerdere lange zijden. De boodschap werd op een lang lint geschreven en dit lint werd dan over de scytale gedraaid. De sleutel gaf aan uit hoeveel vlakken de te gebruiken scytale moest bestaan. Ieder volgend karakter van de plaintext (op het lint) kwam op een andere zijde te liggen. Vervolgens werden alle letters op één zijde achter elkaar gezet, en dit werd herhaald voor iedere zijde: dit werd de ciphertext die werd doorgestuurd.
Om nu de ciphertext te decrypteren werd een onbeschreven lint over de juiste scytale gelegd. Vervolgens werd de verkregen ciphertext op dit lint, zijde per zijde, overgeschreven. Als de ontvanger dan het lint ontrolde kreeg hij terug de originele tekst te zien.
Stel dat we de tekst “De perzen komen er nu aan” (bron: wikipedia) over een scytale met vier zijden wikkelen, dan krijgen we:
De ciphertext die we vervolgens versturen (wanneer we het lint afwikkelen) wordt:
Uiteraard zijn er tal van varianten mogelijk om transpositie te doen. Eerst kan je beslissen om je plaintext in een bepaalde vorm te plaatsen: bijvoorbeeld in tien kolommen. Vervolgens kan je dan, gebaseerd op de sleutel, beslissen in welke volgorde je de kolommen achter elkaar plaatst om zo de ciphertext te bekomen. Dit is een zogenaamd route cipher wat onder andere werd gebruikt tijdens de Amerikaanse Burgeroorlog.
3.3.4 Combinatie
Het spreekt voor zich dat een combinatie van een transpositiecipher en een substitutiecipher je encryptie nog versterkt. Veel moderne algoritmen kunnen nog steeds herleid worden tot een sequentie van meerdere basisvormen na elkaar.
De Advanced Encryption Standard (AES) is in de 21e eeuw zo’n beetje de de facto standaard als het aankomt op symmetrische encryptie (d.w.z. encryptie waar maar één sleutel voor nodig is, verder meer hierover). Als we echter eens het algoritme opengooien en een enkele encryption round bekijken (AES bestaat uit een sequentie van deze rondes) dan zien we dat de bits die bovenaan binnenkomen (state) vervolgens een combinatie van substituties (sub) en transposities (mixcolumns en shiftrows) ondergaan.
We gaan AES nog terug zien opduiken wanneer we gaan bekijken hoe draadloze netwerken worden beveiligd. Als Belg mogen we trouwens erg fier zijn op deze wereldwijd gebruikte Amerikaanse standaard. Je zal later ontdekken waarom dat zo is!
Doel van dit hoofdstuk is ook aantonen dat je geen wiskundig wondertalent moet zijn om de basisconcepten van cryptografie te begrijpen. Hier en daar neem ik wat vrijheden om bepaalde stappen te vereenvoudigen, maar de essentie van de algoritmen blijft wel bewaard en daarmee, hopelijk, ook de eenvoud (en dus elegantie) ervan.
3.4 Cryptanalyse
De term cryptanalyse is nu al enkele keren gevallen: de wereld van de cryptologie bestaat uit twee delen, die elkaars tegengestelden zijn:
- Cryptografie: de wetenschap van het versleutelen van informatie.
- Cryptanalyse: de wetenschap van het ontcijferen van versleutelde informatie, zonder kennis van de gebruikte sleutel.
We gaan in dit boek niet te veel tijd aan de wondere wereld van cryptanalyse spenderen, daar dit ons te ver zou brengen. We vatten echter even de belangrijkste concepten hier samen.
3.4.1 Sleutellengtes en bruteforcen
De term bruteforce dekt de lading goed. Letterlijk vertaald wordt het: met brute kracht forceren. Kortom, je gebruikt het wanneer je niet weet wat doen tijdens de cryptanalyse en gewoonweg de minst efficiënte manier mogelijk zal toepassen, maar waarvan wel geweten is dat ze altijd zal werken. Namelijk iedere mogelijke sleutel testen die het cipher toelaat.
Zoals je je kan inbeelden is de sleutellengte evenredig met de tijd die cryptanalysten nodig hebben om je sleutel te bruteforcen. De maximale tijd die nodig is alle sleutels van een bepaalde lengte te berekenen kan je als volgt vinden:
\(MaximaleTijd = \frac{AantalMogelijkeTekens^{SleutelLengte}}{pogingen/seconde}\)
3.4.1.1 Een bruteforce getalvoorbeeld
Een sleutel (of wachtwoord) bestaat uit 8 tekens, enkel kleine letters van a tot en met z zijn toegestaan. De berekeningen worden op een GeForce GTX 1080 gedaan die ongeveer 30 miljoen pogingen per seconde kan doen. We krijgen dan:
\(MaximaleTijd = \frac{26^{8}}{30000000}\)
Oftewel ongeveer 6960 seconden, wat neerkomt op ongeveer 1,9 uur tijd benodigd om alle mogelijke sleutels te testen (herinner je eraan dat deze tijd gehalveerd moet worden om te weten hoe lang het gemiddeld zal duren om de juiste sleutel terug te vinden.
Volgende tabel (bron) toont nog voorbeelden waarbij telkens dezelfde GeForce 1080 GTX kaart werd gebruikt. Het getal tussen haakjes geeft aan hoeveel mogelijke tekens er in dit type mogelijk zijn:
| # tekens | enkel nummers (10) | kleine letters (26) | grote & kleine letters & nummers (62) | eender welk teken (95) |
|---|---|---|---|---|
| 4 | 0,3 ms | 15 ms | 490 ms | 2,7 s |
| 5 | 3 ms | 400 ms | 31 s | 4,3 min |
| 6 | 33 ms | 10 s | 32 min | 6,8 uur |
| 7 | 330 ms | 4,5 min | 33 uur | 27 dagen |
| 8 | 3,3 s | 1,9 uur | 84 dagen | 7 jaren |
| 9 | 33 s | 2,1 dagen | 14 jaren | 670 jaren |
| 10 | 5,6 min | 54 dagen | 890 jaren | \(6,3*10^{4}\) jaren |
| 11 | 56 min | 3,9 jaren | \(5,5*10^{4}\) jaren | \(6*10^{6}\) jaren |
| 12 | 9,3 u | 100 jaren | \(3,4*10^{6}\) jaren | \(5,7*10^{8}\) jaren |
| 13 | 3,9 dagen | \(2,6*10^{3}\) jaren | \(2,1*10^{8}\) jaren | \(5,4*10^{10}\) jaren |
| 14 | 39 dagen | \(6,8*10^{4}\) jaren | \(1,3*10^{10}\) jaren | \(5,1*10^{12}\) jaren |
| 15 | 1,1 jaar | \(1,8*10^{6}\) jaren | \(8,1*10^{11}\) jaren | \(4,9*10^{14}\) jaren |
| 16 | 11 jaar | \(4,6*10^{7}\) jaren | \(5*10^{13}\) jaren | \(4,7*10^{16}\) jaren |
Per verdubbeling van het aantal GeForce-kaarten halveert de tijd.
Om bovenstaande gigantische getallen wat te duiden: de leeftijd van ons universum wordt op 13,8 miljard jaar geschat, oftewel \(1,38*10^{10}\) jaren. Onze mooie blauwe planeet is ongeveer 4,5 miljard jaar oud. De Tyrannosaurus Rex liep ongeveer 70 miljoen jaar geleden rond, oftewel \(7*10^{7}\) jaren geleden.
3.4.1.2 Dictionary attack
Wanneer de cryptanalist vermoedt dat de te zoeken sleutel iets anders is dan volledig willekeurige tekens dan kan hij de bruteforce aanval verbeteren (denk aan “administrator2022”). In plaats van alle mogelijke combinaties (permutaties) van de sleutel te testen, zal hij een woordenboek (dictionary) gebruiken met daarin alle mogelijke sleutels en woorden die mogelijk de originele sleutel bevatten.
Tools zoals John The Ripper kan je voeden met een dergelijk woordenboek en dan vragen om sleutels te testen die gebaseerd zijn op zaken uit dat woordenboek, inclusief bijvoorbeeld door er tekens voor en na te zetten. Als in het woordenboek het woord god staat, dan kan John The Ripper bijvoorbeeld ook alle sleutels testen zoals god1, god2, etc.
Er zijn tal van woordenboeken online te downloaden die gevuld zijn met de meest gebruikte wachtwoorden die cryptanalisten (en dus ook de digitale stropers) kunnen gebruiken om de sleutel sneller te vinden. Het is aangeraden om zeker geen wachtwoorden (of permutaties ervan) te gebruiken die in volgende lijsten voorkomen: https://github.com/danielmiessler/SecLists/tree/master/Passwords/Common-Credentials
Dit waren in 2020 de 10 meest gebruikte wachtwoorden:
123456, password, 12345678, qwerty, 123456789, 12345, 1234, 111111, 1234567, dragon
Dit soort lijsten worden opgesteld door gekende datalekken te analyseren op welke wachtwoorden er in voorkomen.
3.4.2 Soorten cryptanalytische aanvallen
Geregeld zullen we in dit boek bepaalde zwakheden beschrijven die in algoritmes misbruikt kunnen worden door een bepaald type cryptanalytische aanval. Deze aanvallen zijn afhankelijk van de informatie die de cryptanalist bezit:
- Enkel de ciphertext: vanuit het standpunt van de cyberboswachters is dit het beste soort informatie dat de aanvaller bezit. Hij heeft enkel een hoop geëncrypteerde informatie en moet proberen daar de originele plaintext uit te krijgen. Vanuit het standpunt van de cryptanalist is dit dus de minst goede situatie om vanuit te starten.
- Gekende plaintext: de cryptanalist heeft één of meerdere stukken informatie waarvan zowel de ciphertext als de bijhorende plaintext gekend is.
- Gekozen plaintext: de cryptanalist kan zelf plaintext kiezen waarvan de bijhorende ciphertext moet gemaakt worden. Dit zorgt ervoor dat de cryptanalist als het ware kan experimenteren.
- Gekozen ciphertext: het zelfde concept als gekozen plaintext maar deze keer kiest de cryptanalist de ciphertext waarvan hij de bijhorende plaintext wil genereren.
Er zijn nog enkele meer gespecialiseerde types, maar voor deze cursus zullen we het bij deze vier basistypes houden.
Er wordt in deze sectie soms over aanvaller gesproken, alsof de cryptanalist automatisch van kwade wil is. De wetenschap van de cryptanalyse is dat uiteraard verre van: enerzijds zorgt het ervoor dat bestaande en nieuwe cryptografische algoritmes op hun sterkte kunnen getest worden. Anderzijds helpen ze in tijden van oorlog om boodschappen van vijanden te onderscheppen en proberen lezen.
3.4.3 De menselijke factor: de échte beste “cryptanalyse”
Tijd voor een ongemakkelijke waarheid: de meest effectieve aanval op een cryptografisch systeem is in de praktijk géén cryptanalyse. Het is véél goedkoper, sneller en betrouwbaarder om de sleutel gewoon te vragen aan de gebruiker. Een welgemikte phishingmail, een vervalste helpdeskoproep, een post-it onder het toetsenbord, of een collega die “even snel” z’n scherm ontgrendelt — dát zijn de aanvallen waar cyberboswachters écht wakker van liggen.
There is no patch for human stupidity, is een vaak gehoord cliché in de security-wereld. Hoe sterk je algoritme ook is, hoe lang je sleutel ook, als de gebruiker z’n wachtwoord opschrijft op een briefje of doorgeeft aan wie er “vriendelijk om vraagt”, dan valt heel je cryptografische kaartenhuis in elkaar.
Deze categorie aanvallen noemen we social engineering en we behandelen ze uitgebreid in een later hoofdstuk. Onthoud voor nu: cryptografie is een noodzakelijke voorwaarde voor veiligheid, maar zelden voldoende.
3.4.4 En wat met quantum-computers?
Al jaren houdt de crypto-wereld angstvallig de ontwikkelingen in de quantum-computer wereld in het oog. Alhoewel we nog maar in de babyfase van quantum-computers zijn, is het toch best mogelijk dat binnen afzienbare tijd (20, 30 jaar?) we effectief zodanig sterke quantum-computers zullen hebben die alle bestaande cryptografische systemen in een handomdraai kunnen “kraken”.
Daarom hanteren veiligheidsdiensten al vele decennia ook het store now, decrypt later principe. Ze gaan ervan uit dat computers steeds krachtiger worden: berichten die in de jaren 60 werden versleuteld, kunnen nu in een handomdraai ontcijferd worden. Quantum-computers zullen dit proces nog veel sneller maken.
Hoe dit zal gebeuren snapt de auteur ook (nog) niet en zal dus niet verder uitgewerkt worden in dit handboek. Besef gewoon dat quantum-computers van de toekomst potentiële bruteforce aanvallen drastisch zullen kunnen versnellen.
Het is om deze reden dat er nu reeds onderzoek wordt gedaan naar cryptografische ciphers die bestand zullen zijn tegen de computers van de toekomst. Dit soort ciphers worden post-quantum cryptografische ciphers genoemd en zullen niet in dit boek besproken worden.
Trouwens, ook andere systemen die gebruik maken van cryptografische concepten zullen in één klap hun nut verliezen. Of zoals dit artikel zegt “And [as ]encryption is everywhere in modern day life, from e-commerce, to online payments, to passwords, everything will be vulnerable!”
Denk daarbij bijvoorbeeld aan cryptocurrencies zoals Ethereum en Bitcoin:
Cybersecurity specialist Itan Barmes led the vulnerability study of the Bitcoin blockchain. He found the level of exposure that a large enough quantum computer would have on the Bitcoin blockchain presents a systemic risk. “If [4 million] coins are eventually stolen in this way, then trust in the system will be lost and the value of Bitcoin will probably go to zero,” he says. Bron
3.5 Moderne cryptosystemen
De klassieke ciphers die we tot nu toe zagen — Caesar, Vigenère en scytale — zijn fantastisch om de basisprincipes van substitutie en transpositie uit te leggen, maar in de praktijk vallen ze ondertussen om als een kaartenhuis. Caesar kraak je in maximaal 25 pogingen, Vigenère valt na Kasiski’s truc terug op een handvol parallelle Caesars, en de sleutelruimte van een scytale beperkt zich tot het aantal vlakken dat redelijkerwijs op een stok past. Tegen de rekenkracht van vandaag (denk terug aan de bruteforce-tabel hierboven) houdt geen enkel klassiek algoritme nog stand.
Moderne cryptografische systemen zijn dan ook compleet anders opgebouwd:
- Veel grotere sleutelruimtes (128, 192, 256 bits en meer) waardoor bruteforce praktisch onhaalbaar wordt.
- Iteratief: niet één enkele substitutie, maar tientallen rondes van substitutie én transpositie achter elkaar, waardoor statistische patronen volledig verdwijnen.
- Publiek ontworpen en getest door duizenden experts wereldwijd (Kerckhoffs in actie) → géén security through obscurity.
- Wisselende subkeys per ronde, afgeleid uit de hoofdsleutel. Eigenlijk het idee van Vigenère, maar dan op steroïden.
Wanneer we deze moderne systemen klasseren volgens het aantal sleutels dat ze gebruiken, vallen ze in twee grote families:
- Symmetrische systemen: zender en ontvanger gebruiken dezelfde sleutel.
- Asymmetrische systemen: er zijn twee sleutels — één publiek (om te encrypteren) en één privaat (om te decrypteren).
We starten met de oudste van de twee, de symmetrische cryptosystemen. Verderop in dit hoofdstuk komen de asymmetrische aan bod, en zal blijken dat beide families elkaar in de praktijk perfect aanvullen.
3.6 Symmetrische encryptie
Symmetrische systemen zijn de oudste vorm van encryptie: zowel ontvanger als verzender gebruiken dezelfde sleutel. De term symmetrisch verwijst naar het feit dat het algoritme exact hetzelfde doet aan beide zijden. Het enige verschil is dat bij de verzender de plaintext in het systeem wordt gestoken, wat resulteert in een ciphertext. Terwijl de ontvanger de ciphertext in het systeem plaatst om een plaintext te krijgen.
De symmetrische encryptiesystemen zijn de oudste vorm: alle klassieke algoritmes waren van dit principe. Asymmetrische systemen zijn pas in de 20e eeuw ontwikkeld (circa 1970).
Voorbeelden van bestaande symmetrische encryptiesystemen zijn: AES, DES, IDEA, RC4, Blowfish, etc.
Dit type encryptie is nog steeds het meest gebruikte en wordt overal gebruikt waar data op een veilige manier (confidentiality) moet bewaard, verstuurd of verwerkt worden.
3.6.1 Sleuteloverdracht
De moeilijkheid bij symmetrische systemen is de sleuteloverdracht. Daar ontvanger en verzender dezelfde sleutel hanteren is het natuurlijk belangrijk dat deze de sleutel op een veilige manier kunnen uitwisselen. Dit probleem wordt niet opgelost door symmetrische cryptosystemen. Afhankelijk van de context kan deze uitwisseling op verschillende manieren gebeuren:
- Via een asymmetrisch encryptiesysteem dat wél sleutels op een veilige manier kan uitwisselen (zie verder).
- Via een ander beveiligd kanaal, in eender welke vorm (bijvoorbeeld fysiek de sleutel aan de andere persoon geven of zeggen, deze opsturen via een reeds opgezet symmetrisch encryptiekanaal, etc.).
3.6.2 Block- en streamciphers
Er zijn twee soorten symmetrische encryptieciphers als we kijken naar de manier waarop ze de te encrypteren data verwerken:
- Streamciphers: hierbij wordt de data letterlijk als een stroom (stream) van tekens beschouwd. Waarbij teken per teken individueel geëncrypteerd wordt (het bekendste voorbeeld is RC4). Voor ieder teken dat verwerkt wordt zal er exact één geëncrypteerd teken gegenereerd worden. Dit soort algoritmes zijn over het algemeen sneller dan blockciphers.
- Blockciphers: de data wordt in blokken (van bijvoorbeeld 128 tekens) verwerkt. Bekendste voorbeelden die we verderop behandelen zijn AES, DES, 3DES, etc.
3.6.3 Streamciphers
De werking van een symmetrisch streamcipher is verrassend eenvoudig en bestaat uit twee delen:
- Een pseudorandom keystream generator: deze zal de sleutel als het ware expanderen naar een sleutel met de zelfde lengte als de stream, genaamd een keystream. Als je 400 bytes aan data wenst te encrypteren, zal je een keystream van 400 bytes moeten genereren. Daar we met een stream werken zal deze generator teken per teken genereren. Hoe dit gebeurt, leggen we verderop uit.
- De XOR of “exclusieve of” functie: deze zal de plaintext naar een ciphertext omzetten door de plaintext met de keystream samen te voegen. Deze stap is de feitelijke encryptie!
Aan de ontvangerzijde gebeurt exact hetzelfde. Enkel indien de ontvanger dezelfde sleutel gebruikt, zal deze dezelfde keystream kunnen genereren, en bijgevolg enkel dan de originele plaintext verkrijgen.
Het hart van een symmetrisch streamcipher is dus enerzijds de XOR-functie én, belangrijker, de manier waarop de keystream wordt gemaakt.
3.6.3.1 De XOR functie
De waarheidstabel van de XOR-functie is de volgende:
| Plaintext input | Keystream input | Ciphertext output |
|---|---|---|
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
| 1 | 1 | 0 |
De XOR-functie wordt in schema’s aangeduid door een cirkel met een plusje in: \(\oplus\)
Beeld je in dat we het bericht 1010 willen versleutelen, en we hebben een gegenereerde keystream 1101. Als we deze XOR’n dan geeft dit 0111. Dit is dus de ciphertext. Als de ontvanger dezelfde keystream kan genereren en deze XOR’d met de verkregen ciphertext, dan krijgt deze terug de originele plaintext.
3.6.3.2 De keystream generator
De keystream generator heeft dus als doel om voor ieder karakter dat moet geëncrypteerd worden een bijhorend keystream karakter te maken. Deze karaktergeneratie moet onvoorspelbaar zijn (random) tegenover de sleutel die wordt gebruikt en het voorgaande karakter dat werd gemaakt. Echter, dit moet wel PSEUDO (schijn)-willekeurig zijn: dezelfde sleutel als beginpunt (seed) moet steeds dezelfde reeks genereren.
De kracht (en zwakte) van een symmetrisch streamcipher ligt in de implementatie van de manier waarom deze keystream generator werkt. Mogelijke zwakheden kunnen bijvoorbeeld zijn dat de gegenereerde stroom informatie van de sleutel “lekt” naar de keystream (wat desastreuze gevolgen bleek te hebben bij de originele wifi-security (WEP), waarover later meer) of een voorspelbare “randomiteit” van de keystream.
Om aan encryptie te kunnen doen, hebben we systemen nodig die onvoorspelbaar zijn. Als de aanvaller kan voorspellen wat de uitvoer van een onderdeel van de encryptie zal zijn, dan kunnen we geen confidentiality en integrity voorzien. Kortom, we hebben algoritmes nodig die willekeurige getallen kunnen generen die 100% onvoorspelbaar zijn. Net zoals het werpen van een dobbelsteen niet voorspeld kan worden, zo ook moeten onze algoritmes een (digitale) dobbelsteen hebben.
Digitale systemen die perfect willekeurige getallen genereren noemt men random number generators (RNG). Uiteraard moet een RNG geprogrammeerd kunnen worden: dat behelst dus een algoritme. Een algoritme is per definitie “voorspelbaar”. Alles hangt daarom af van de invoer die het algoritme gebruikt om random getallen te beginnen genereren. We spreken dan van een pseudorandom number generator (PRNG), pseudo (schijnbaar) omdat de uitvoer afhankelijk is van het startgetal, de zogenaamde seed. Die seed kan bijvoorbeeld de encryptiesleutel zijn: enkel met dié sleutel zal het algoritme dezelfde reeks getallen generen. Er zijn echter ook systemen die bijvoorbeeld de huidige tijd of de staat van een flipflop als startpunt gebruiken (wanneer je een flipflop aanzet kan je niet voorspellen of deze op 1 of 0 zal staan, daar deze staat beïnvloed wordt door de elektromagnetische straling). Uiteraard is een dergelijke seed voor een keystream generator nutteloos, daar zowel verzender én ontvanger dezelfde reeks getallen moeten kunnen genereren.
3.6.3.3 Een eenvoudig PRNG: middle-square
Een van de eerste PRNG-algoritmes werd in 1946 bedacht door de legendarische wiskundige John von Neumann: de middle-square methode. De werking is verbluffend eenvoudig:
- Neem een startgetal (de seed).
- Kwadrateer het.
- Neem de middelste cijfers als volgende pseudo-willekeurig getal.
- Gebruik dat getal opnieuw als invoer voor stap 2, enzovoort.
Laten we dit uitvoeren met seed 1111 (pad tot 8 cijfers zodat we altijd 4 middelste cijfers hebben):
- \(1111^2 = 01234321\) → middelste 4 cijfers:
2343 - \(2343^2 = 05489649\) → middelste 4 cijfers:
4896 - \(4896^2 = 23970816\) → middelste 4 cijfers:
9708 - …
Onze pseudo-willekeurige reeks wordt dus 2343, 4896, 9708, .... Wie met dezelfde seed start, krijgt gegarandeerd dezelfde reeks. En dát is precies wat we willen voor encryptie: zender én ontvanger moeten dezelfde keystream kunnen genereren.
In de praktijk is middle-square ondertussen niet meer bruikbaar: de gegenereerde reeksen vallen snel in korte cycli of landen op 0000 waarna het algoritme vast komt te zitten. Maar het idee - deterministisch uit een seed een schijnbaar willekeurige reeks maken - blijft de basis van alle moderne PRNGs zoals die in RC4.
3.6.3.4 PRNG in de praktijk: Random() in C#
Zo goed als iedere moderne programmeertaal heeft een ingebouwde PRNG. In C# gebruik je new Random(seed), in Python random.seed(), in JavaScript… tja, daar is het een beetje complexer. Een eenvoudig voorbeeld in C# maakt het principe meteen concreet:
int key = 666;
// Zender genereert 10 getallen
Random s = new Random(key);
for (int i = 0; i < 10; i++) Console.Write(s.Next(1, 10));
// Output: 6337963648
// Ontvanger gebruikt dezelfde seed → identieke reeks
Random r = new Random(key);
for (int i = 0; i < 10; i++) Console.Write(r.Next(1, 10));
// Output: 6337963648
// Eve probeert met een andere seed
Random e = new Random(123);
for (int i = 0; i < 10; i++) Console.Write(e.Next(1, 10));
// Output: 9978711226Zender en ontvanger die dezelfde sleutel (seed) gebruiken, krijgen identiek dezelfde reeks — perfect als keystream voor een streamcipher. Zonder de juiste seed krijg je een totaal andere reeks en is de keystream nutteloos voor cryptanalyse.
De ingebouwde Random-klasse in C# is niet cryptografisch veilig. Hij is prima voor games, simulaties of dobbelstenen, maar niet geschikt om data mee te beschermen. Voor écht cryptografisch gebruik neem je de klasse RandomNumberGenerator uit System.Security.Cryptography. Het basisprincipe (seed + deterministisch algoritme = reproduceerbare reeks) blijft wel identiek.
3.6.3.5 RC4 tot op het bot
Laten we eens één van de meest gebruikte streamciphers bekijken, het RC4 cipher. Dit algoritme, ontwikkeld door Ron Rivest (de afkorting staat trouwens voor Rons Cipher 4), wordt gebruikt onder andere om een beveiligde SSL-tunnel (zie later) op te zetten en zit in het hart van veel geëncrypteerde communicatiekanalen.
RC4 werkt zoals we eerder verklaarden hoe een streamcipher werkt: het heeft een keystream generator en zal de keystream vervolgens XOR’n met de plaintext. Eerst zal de ingevoerde sleutel (die 40 tot 2048 bits lang mag zijn) omgezet worden naar een compatibele werksleutel met behulp van een Key scheduling algorithm (KSA). Deze werksleutel zal dan als seed gebruikt worden om een keystream in het Pseudo-random generator algorithm (PRGA) te maken.
3.6.3.5.1 KSA
De KSA heeft als doel om de ingevoerde 40 tot 2k-bit sleutel om te zetten naar een compatibele sleutel voor de PRGA. Het doet dit volgens een eenvoudig algoritme:
Stap 1: plaats de ingevoerde sleutel in een array (T) van 256 karakters. Herhaal de sleutel indien nodig.
Stap 2: maak een sleutelarray (S) aan, ook van 256 karakters, en plaats er de waarden 0 tot en met 255 in.
Stap 3: permuteer (transpositie) de elementen in de array S met behulp van de array T als volgt:
j = 0
for i = 0 tot 255
{
j = (j + S[i] + T[i]) % 256
Verwissel(S[i],S[j])
}
Deze stap zal dus de elementen in de sleutelarray S naar nieuwe posities in diezelfde array plaatsen en deze ook de hele tijd van plek wisselen. De index j is afhankelijk van de originele sleutel uit stap 1 en zorgt er dus voor dat iedere finale sleutel een unieke array S zal opleveren.
Uitgewerkt voorbeeld van KSA
Stel dat onze sleutel “ab” is. De decimale ASCII-waarden van a en b zijn 97 en 98 respectievelijk. Onze array T zal dus bestaan uit 128 keer de waarden 97 en 98 na elkaar aan de start:
| Index | Waarde |
|---|---|
| T[0] | 97 |
| T[1] | 98 |
| T[2] | 97 |
| etc. |
Stap twee genereert de tabel S die gewoon de waarden 0 tot en met 255 heeft in de 255 plekjes van de array (de waarde is dus in deze fase gewoon ook de index van het element)
Als we dan stap drie toepassen dan krijgen we na de eerste iteratie van de loop (i=0):
j = (0 + S[0] + T[0]) % 256
oftewel
j= (0 + 0 + 97) % 256 => j wordt 97
De eerste wissel die in S zal plaatsvinden is dan Verwissel(S[0],S[97])
S ziet er dan als volgt uit na de eerste iteratie:
| Index | Waarde |
|---|---|
| S[0] | 97 |
| S[1] | 1 |
| S[2] | 2 |
| … | |
| S[97] | 0 |
| etc. |
En dit herhalen we nog 255 keer. Finaal hebben we nu in tabel S een sleutel die bestaat uit de getallen 0 tot en met 255 verdeeld over willekeurige plekken in de array. Indien we een andere initiële sleutel zouden hebben gebruikt dan zou deze tabel er totaal anders uitzien.
3.6.3.5.2 PRGA
Nu we een compatibele sleutel S hebben kan de keystream generatie van start gaan. Deze bestaat uit een loop die blijft doorgaan telkens een nieuw plaintext karakter binnenkomt, als volgt:
i = 0
j = 0
Herhaal telkens keystream karakter nodig is
{
i = (i+1) % 256
j = (j +S[i]) % 256
Verwissel(S[i],S[j])
k = S[(S[i]+S[j]) % 256]
output k naar keystream
}
Telkens zal het algoritme één specifieke waarde (tussen 0 en 255) uit de array teruggeven als keystream karakter k. Zoals je ziet zal de array S voorts de hele tijd van “gedaante” blijven veranderen. Telkens we een element k uitsturen zal ook de tabel S weer wat zijn veranderd daar we de waarden van S[i] en S[j] onderling verwisselen.
3.6.3.5.3 Uitgewerkt voorbeeld van PRGA
Als we verder werken met de tabel S van het vorige uitgewerkte KSA voorbeeld en de waarden ervan gebruiken na één iteratie dan krijgen we onderstaande berekeningen (We veronderstellen even dat we de KSA niet verder hebben uitgevoerd en de tabel S dus dezelfde is gebleven als op het einde van het voorbeeld, wat in het echt niet zal zijn.):
i = (0+1) % 256 => 1
j = (0 + S[1]) % 256 => (0+1) % 256 => 1
(S[1] is nog steeds 1: in de KSA-iteratie hebben we enkel S[0] en S[97] gewisseld)
Verwissel(S[1], S[1]) => geen werkelijke wissel, want i en j vallen samen
k = S[ (S[1] + S[1]) % 256 ] => k = S[2] => 2
we outputten de waarde 2 als eerste keystream-karakter
In dit specifieke voorbeeld vallen i en j toevallig samen, waardoor er geen wissel gebeurt. In een realistische PRGA-run (na een volledige KSA van 256 iteraties) is de tabel S echter grondig dooreengeschud en zal vrijwel iedere PRGA-iteratie wél een wissel opleveren.
Finaal zal de output, de waarde k, ge-XOR’d worden met het huidige karakter van de plaintext stream.
Zo, dat viel nog mee he? Zoals al gezegd, een belangrijke motivatie van dit boek is aantonen dat je niet bang hoeft te zijn van wat er achter de schermen van de cyberwereld gebeurt. De hoeveelheid wiskunde die we bijvoorbeeld nodig hadden, is beperkt gebleven tot onze trouwe modulo (%)-operator en meer niet. Wanneer we zo meteen een blockcipher gaan uitkleden, zal je ook daar ontdekken dat je best in staat bent schijnbaar complexe technologieën te begrijpen. Hop naar de blockciphers dus!
3.6.4 Blockciphers
Blockciphers, de naam zegt het al, zullen eerst de plaintext in blokken karakters opdelen (bv. 128 bits) en vervolgens blok per blok encrypteren.
Indien het aantal te encrypteren bytes aan data geen exact veelvoud is van de blokgrootte dient er padding te gebeuren. Hierbij zal het laatste blok opgevuld (gepad) worden met extra bytes tot het blok terug de juiste blokgrootte heeft. De manier waarop de padding gebeurt, is afhankelijk van het cipher dat gehanteerd worden.
3.6.4.1 Feistel-structuren
Ook hier zullen we dezelfde soorten operaties (XOR, substituties en transposities) zien terugkomen. Echter, ook Feistel-structuren worden hier gebruikt: in deze operatie zal de data steeds in twee helften worden gesplitst en wordt steeds een specifieke operatie (aangeduid met F van functie in de figuur), zoals een substitutie, op één helft uitgevoerd dat dan wordt ge-XOR’d met de andere helft. Dit wordt meerdere keren herhaald, waarbij de linker (L) en rechterzijde (R) steeds afwisselend door de specifieke encryptie-operatie gaan.
Net zoals bij RC4 zullen we ook vaak met een zogenaamd key scheduling algoritme werken zodat de sleutel niet constant doorheen het hele proces dezelfde is en we met subkeys of round keys werken.
3.6.4.2 DES tot op het bot
Een van de oudste blockciphers is DES oftewel Data Encryption Standard. Deze standaard werd in 1977 geboren en vereiste toen blokken van 64 bits data en gebruikte een 56bit sleutel. Ondertussen is dit cipher zeer outdated, maar we gaan hem toch bekijken omdat deze enerzijds erg belangrijk was voor de wereld - grote delen van het bankwezen beschermden er hun financiële transacties mee (en nadien met de opvolger 3DES, zie verder) - en de standaard is erg duidelijk om een goed inzicht in blockciphers te verkrijgen.
Er was wel veel controverse rond deze standaard (gebaseerd op het door IBM ontwikkelde Lucifer cipher) omdat de originele versie (genaamd Lucifer) werkte met een dubbel zo grootte sleutel (128 bit) en bijgevolg dus veiliger was op lange(re) termijn. De Amerikaanse veiligheidsdienst, NSA, was niet zo happig om een dergelijk goed beveiligd algoritme commercieel te maken en zorgde er daarom voor dat de sleutellengte gehalveerd werd.
Data met DES encrypteren (en bijgevolg ook decrypteren daar het een symmetrisch cipher is) bestaat uit twee onderdelen:
- Versleuteling: een reeks Feistel-structuren na elkaar (16 rondes) die de data blok per blok versleutelen.
- Subkeys maken: een key scheduling algoritme dat 16 subkeys genereert (één voor iedere encryptieronde), gebaseerd op de 56 bit sleutel.
3.6.4.2.1 Versleuteling
Volgende schema toont de encryptie bestaande uit 16 rondes:
De data wordt blok per blok doorheen dit gedeelte gestuurd. Eerst gebeurt er een Initiële Permutatie (IP in de figuur) waarbij iedere bit naar een andere plek wordt gestuurd volgens een vast patroon. Achteraan gebeurt dit nogmaals in een Finale Permutatie (FP).
Na de IP gaat de data door 16 Feistel-structuren die telkens hetzelfde doen. De data wordt in twee helften gesplitst waarbij de rechterzijde door de F-operatie gaat (die we zo meteen toelichten), het resultaat hiervan wordt ge-XOR’d met de linkerhelft van de data. Het resultaat van deze XOR, een 32 bit blok, wordt nu het rechterblok in de volgende ronde en omgekeerd.
In het F-blok wordt eerst het 32-bit blok uitgebreid (E in de figuur, van expansie) naar een 48 bit blok zodat deze even lang is als de subkey voor deze ronde. De expansie gebeurt, net als de initiële permutatie, volgens een vast patroon:
Nu worden deze 48 bits ge-XOR’d met de subkey. Het resultaat wordt in blokjes van 6 bits door een S-blok gestuurd (zogenaamde Selection blocks). In dit blokje wordt 6 bit omgezet naar 4 bit. In de figuur hieronder zien we bijvoorbeeld hoe de omzetting in blok S5 gebeurt. Ieder blokje heeft een soortgelijke tabel, maar met andere resultaten. De 6 bits bestaan uit de 2 outer bits, namelijk de eerste en de laatste bit, alsook de 4 innerbits. De outer bits vormen de rij-index in de S-box-tabel, de inner bits de kolom-index. De figuur toont bijvoorbeeld dat de output 1001 zou zijn indien er 011011 in het blok wordt geplaatst: outer bits 01 wijzen naar rij 1, inner bits 1101 naar kolom 13, en op die positie in de S5-tabel staat de waarde 1001.
Na 16 rondes krijgen we terug een 32 bit datablok dat nog een Finale permutatie ondergaat die weer de bits van plaats verandert en de output hiervan is een geëncrypteerd blok data dat kan doorgestuurd worden naar de ontvanger.
Je kan de DES standaard op web.archive.org/web/20040410171758/http://www.itl.nist.gov/fipspubs/fip46-2.htm nalezen en ontdekken dat deze niet zo lang is zoals je zou verwachten van een wereldwijd gebruikte standaard.
3.6.4.2.2 Subkeys maken
Iedere ronde tijdens de versleuteling vereist een sleutel. Om te voorkomen dat steeds de hoofdsleutel wordt gebruikt (en er zo potentieel dezelfde keystreams worden gemaakt), wordt deze sleutel doorheen een round-key generator algoritme gestuurd. Dit algoritme bestaat uit 16 rondes waarbij de 56 bit sleutel (8 van de 64 bits in de originele sleutel zijn zogenaamde pariteits-bits, die dienen om te controleren of de sleutel geen fouten bevat) steeds in twee helften van 28 bits wordt geknipt.
Iedere ronde wordt de helft van de sleutel 2 bits geshift (in ronde 1,2, 9 en 16 maar 1 bit). Dat wil zeggen dat alle bits twee plekjes opschuiven en de eerste (of laatste) bits komen dan achteraan (of vooraan) te staan. Deze twee geshifte helften worden dan enerzijds doorgestuurd naar de volgende ronde, anderzijds naar een compressie P-box waarvan het resultaat een 48 bits subkey zal zijn van die ronde.
De naam compressie P-box doet al vermoeden wat er gebeurt:
- Compressie: een aantal bits zullen wegvallen (er komen 56 bits in, maar we hebben maar 48 bits nodig).
- P-box: een permutatie oftewel transpositie dat alle bits van plek zal veranderen.
In de Compression P-Box wordt een aantal bits van de sleutel “tegengehouden”. Welke bits dat zijn hangt af van de P-Box. Iedere ronde wordt er een andere Compression P-Box gehanteerd.
En zo hebben we het einde van de werking van DES bereikt. Dat viel al bij al nog mee, niet?
3.6.4.3 3DES
Al van bij de start gingen er stemmen op dat de originele sleutellengte voor DES (56 bits, 48 in effectiviteit vanwege de pariteitsbits) redelijk snel zou gebruteforced worden. Om die reden werd 3DES in het leven geroepen in 1995. De oplossing, 3DES, was een mooi staaltje compromisvorming: het bood een verhoogde beveiliging doordat het een lange sleutel had (tot 168 bits lang) maar bleef tegelijkertijd compatibel met de bestaande DES hardware en software.
De werking van 3DES (triple DES) is verrassend eenvoudig: ieder blok data wordt drie keer doorheen een DES-cipher gestuurd, telkens met een andere sleutel. Om compatibel te blijven met bestaande DES hardware wordt de data hierbij eerst Encrypted, dan Decrypted, en tenslotte opnieuw Encrypted. Dit patroon wordt daarom het EDE-schema (Encrypt-Decrypt-Encrypt) genoemd. Daar we in iedere fase een andere sleutel gebruiken, heeft dit (dankzij de eigenschappen van symmetrische ciphers) als effect dat we effectief drie maal na elkaar encrypteren met steeds een andere sleutel. Aan de ontvangerzijde gebeurt het omgekeerde — decryptie, encryptie, decryptie (DED) — en ook dit met dezelfde DES hardware!
3DES laat dus ook (single) DES encryptie toe. Het enige dat je hiervoor moet doen is de subsleutels K2 en K3 gelijkstellen waardoor de tweede en derde fase tijdens de encryptie (en decryptie) eigenlijk niets doen, daar het gewoon de data encrypteert in ronde twee en dan ogenblikkelijk in ronde drie terug decrypteert.
Het bankwezen gebruikt 3DES nog steeds (of varianten die erop gebaseerd) zijn om financiële transacties van onder andere Visa en Mastercard te beveiligen.
3.6.4.4 DES in de praktijk gekraakt: EFF Deep Crack
De zorgen om de korte 56-bit sleutel van DES werden in 1998 op spectaculaire wijze bevestigd. De Electronic Frontier Foundation (EFF) bouwde voor ongeveer $250.000 een gespecialiseerde machine, bijgenaamd Deep Crack, die bestond uit 1.856 custom chips die speciaal ontworpen waren om DES-sleutels te testen.
Het resultaat? Deep Crack kon iedere willekeurige DES-sleutel in een kwestie van dagen bruteforcen. Een paar jaar later deed het project, in samenwerking met distributed.net, een DES-sleutel zelfs in minder dan 24 uur. Daarmee werd ondubbelzinnig aangetoond dat DES niet langer veilig was voor gevoelige data — exact wat critici al jaren beweerden.
Dit was eigenlijk geen verrassing voor wie had opgelet: de NSA had bij de originele Lucifer-standaard de sleutellengte van 128 bits naar 56 bits laten halveren. Een toevalligheid? Critici waren al jaren overtuigd van niet. Deep Crack bevestigde hun vermoeden op de meest publieke manier mogelijk en gaf zo ook retroactief gelijk aan de keuze voor 3DES in 1995.
Bij de publieke aankondiging werd een versleuteld bericht gekraakt in 56 uur. Het bericht? “It’s time for those 128-, 192-, and 256-bit keys.” Een niet zo subtiele boodschap aan de industrie om over te schakelen naar sterkere algoritmes. In 2001 gebeurde dat effectief, met de komst van AES (zie verder).
3.6.4.5 Block cipher modes
Tot hiertoe gingen we data steeds blok per blok in het encryptiecipher sturen en het resultaat ervan doorsturen. Klaar. Oplettende mensen hebben hier mogelijk al een hiaat in gezien: wat als twee blokken exact dezelfde data bevatten? Beiden zullen dezelfde ciphertext als resultaat genereren, daar we telkens dezelfde sleutel (en dus subkeys) gebruiken. Twee ciphertexts die identiek zijn, willen we vermijden daar het potentiële informatie over de plaintext zichtbaar maakt. Voorts laat dit soort werking ook replay attacks toe: de aanvaller kan een geëncrypteerd pakket bewaren en op een later moment terug opsturen, zonder dat hij moet weten wat de plaintext bevat.
Stel dat we een afbeelding van Tux De Pinguïn opsplitsen in ongeveer 100 bij 100 datablokken. Als we nu ieder blok individueel met een blockcipher encrypten en zouden visualiseren dan krijgen we iets dat mogelijks toch nog wat informatie van Tux doorlekt (zie de tweede afbeelding) daar blokken van de afbeelding met exact dezelfde informatie ook dezelfde ciperblock zullen genereren. Vergelijk dit met de derde afbeelding waarin we een andere modus gebruiken (die we zo meteen gaan uitleggen) waarin repetities in de plaintext geen invloed hebben op repetities in de ciphertext.
Voorgaande modus, waarin we ieder blok onafhankelijk van het vorige encrypteren, noemen we de Electronic Codebook (ECB) modus.
Alhoewel deze modus dus duidelijk een veiligheidsprobleem met zich mee draagt, heeft deze modus ook één voordeel:
- Ieder blok wordt onafhankelijk van andere blokken gedecrypteerd. Als er dus een blok niet gedecrypteerd kon worden door een fout, dan heeft dat geen invloed op de daaropvolgende blokken. Dit is dus voor streaming-situaties nuttig: beeld je in dat je decryptie faalt halverwege het binnenkrijgen van een film die je aan het bekijken bent. Je zou helemaal opnieuw moeten beginnen.
ECB is een niet zo veilige manier om een blockcipher toe te passen. Veel interessanter (veiliger) wordt het wanneer we extra informatie gebruiken om een blok te encrypteren. Enkel het huidige blok en dezelfde sleutel gebruiken is namelijk niét veilig.
Er zijn verschillende modes om veiliger te encrypteren dan ECB. We bespreken hieronder de belangrijkste.
3.6.4.5.1 CBC (Cipher Block Chaining)
Bij CBC wordt de output van het vorige blok (de ciphertext) mee als input voor de encryptie van het volgende blok gebruikt. Concreet wordt de ciphertext van het vorige blok ge-XOR’d met het huidige plaintext-blok, vóór de encryptie plaatsvindt. Hierdoor is de encryptie van elk blok afhankelijk van alle voorgaande blokken, wat patronen in de plaintext verbergt.
Laten we dit concreet maken met een minimalistisch voorbeeld. Stel dat ons blockcipher maar 2 bits per blok verwerkt, volgens volgende substitutietabel:
| Input | Output |
|---|---|
| 00 | 01 |
| 01 | 10 |
| 10 | 11 |
| 11 | 00 |
Onze plaintext is 00 01 10 11 (vier blokken), onze IV is 10. De CBC-encryptie verloopt dan als volgt:
| Blok | Plaintext | XOR met | Na XOR | Door cipher | Ciphertext |
|---|---|---|---|---|---|
| 1 | 00 |
IV=10 |
10 |
→ 11 |
11 |
| 2 | 01 |
11 |
10 |
→ 11 |
11 |
| 3 | 10 |
11 |
01 |
→ 10 |
10 |
| 4 | 11 |
10 |
01 |
→ 10 |
10 |
De uiteindelijke ciphertext wordt 11 11 10 10. Merk op dat onze vier plaintext-blokken allemaal verschillend waren (00, 01, 10, 11), maar dat er in de ciphertext toch herhalingen verschijnen (11 11 en 10 10). Dat is exact wat we willen: repetities in de ciphertext dragen géén informatie meer over repetities in de plaintext. De link tussen patronen in plaintext en ciphertext is doorgeknipt.
3.6.4.5.2 CFB (Cipher Feedback)
CFB werkt vergelijkbaar met CBC, maar de ciphertext van het vorige blok wordt iets later in het encryptieproces van het volgende blok gebruikt. Het vorige ciphertext-blok wordt eerst door het blockcipher gestuurd en daarna ge-XOR’d met de plaintext.
3.6.4.5.3 OFB (Output Feedback)
Bij OFB wordt het blockcipher als een streamcipher gebruikt: de output van het blockcipher wordt telkens opnieuw als input voor het blockcipher gebruikt om een keystream te genereren. Deze keystream wordt vervolgens ge-XOR’d met de plaintext.
3.6.4.5.4 CTR (Counter Mode)
CTR is één van de meest gebruikte modes en werkt fundamenteel anders dan CBC of CFB. In plaats van blokken aan elkaar te ketenen, wordt een teller (counter) als input voor het blockcipher gebruikt. Deze teller bevat een Initialisatie Vector (IV) die bij elk volgend blok met 1 wordt verhoogd.
De werking is als volgt: het blockcipher encrypteert niet de plaintext zelf, maar de tellerwaarde. Het resultaat hiervan wordt vervolgens ge-XOR’d met het plaintext-blok om de ciphertext te bekomen. Doordat elk blok een unieke tellerwaarde gebruikt, levert dezelfde plaintext in verschillende blokken steeds andere ciphertext op.
Een groot voordeel van CTR is dat blokken parallel verwerkt kunnen worden: de encryptie van blok 5 is volledig onafhankelijk van blok 4, aangezien enkel de tellerwaarde en de sleutel nodig zijn. Dit maakt CTR bijzonder geschikt voor toepassingen waar snelheid belangrijk is, zoals bij het streamen van video (denk aan Netflix). CTR wordt onder andere gebruikt in WPA2 en IPSEC.
3.6.4.5.5 Overige modes
Naast bovenstaande modes bestaan er nog andere, zoals Propagating CBC (PCBC), waarbij bij decryptie van een blok ook alle vorige blokken vereist zijn. Alle modes uit de doeken doen is hier niet aan de orde, maar het moge duidelijk zijn dat ECB de minst veilige mode is en deze best vermeden wordt.
Het concept Initialisatie Vector (IV) zal je veel zien terugkomen in ciphers. Een IV is een getal dat men als extra seed meegeeft tijdens de encryptie, naast de sleutel. Op deze manier voorkomen we dat steeds enkel de sleutel als seed wordt gebruikt en we dus effectief steeds met een andere sleutel werken. Uiteraard zal ook de andere zijde over dezelfde IV moeten beschikken en zal deze dus doorgestuurd moeten worden. Dit gebeurt meestal via de header van het bijhorende pakketje en is ongeëncrypteerd. Dit lijkt contra-intuïtief - de IV onbeveiligd doorsturen - maar is geen probleem. Uiteraard is het belangrijk dat er een goed IV selectie algoritme wordt gebruikt dat bepaalt hoe steeds het volgende IV moet worden berekend (bv. steeds met 1 verhogen, een willekeurig, etc.).
3.6.4.6 AES
Alhoewel 3DES een verbetering op DES was, was er toch nood aan een nieuwe encryptie-standaard die langere tijd kon bestaan. In 2001 werd daarom de Advanced Encryption Standard (AES) boven het doopvont gehouden als de nieuwe de facto encryptiestandaard wereldwijd. Deze Amerikaanse standaard is gebaseerd op het Rijndael-algoritme waar we als Belgen fier op mogen zijn: Rijndael is ontwikkeld door twee Belgische KUL-cryptografen Vincent Rijmen en Joan Daemen.
AES is een symmetrisch blockcipher dat data in blokken van 128 bits zal opsplitsen en sleutels tot 256 bits lang toelaat. De volledige werking van AES gaan we hier niet uit de doeken doen, het voldoet te begrijpen dat in grote lijnen hetzelfde soort stappen worden doorlopen als DES en andere symmetrische ciphers:
- KeyExpansion: uit de hoofdsleutel worden alle round keys afgeleid (één per ronde, net zoals bij DES).
- De data wordt vervolgens doorheen 10, 12 of 14 rondes gestuurd, afhankelijk van de sleutellengte (respectievelijk 128, 192 of 256 bits). Het te encrypteren blok wordt daarbij voorgesteld als een 4×4-matrix van bytes, de zogenaamde state.
- Iedere ronde bestaat uit vier vaste stappen op die state:
- SubBytes — iedere byte wordt via een vaste S-box vervangen door een andere byte (substitutie).
- ShiftRows — de rijen van de state worden cyclisch verschoven (transpositie).
- MixColumns — binnen iedere kolom worden de bytes met elkaar gemengd via een lineaire transformatie (zorgt voor diffusie). Deze stap valt weg in de allerlaatste ronde.
- AddRoundKey — de state wordt ge-XOR’d met de round key van die ronde. Dít is waar de sleutel opnieuw in de encryptie binnenkomt.
Merk op dat ook hier, in de AddRoundKey-stap, de XOR-functie nog steeds dienst zal doen als de feitelijke encryptie van de data. Zonder deze XOR-functie zou al het voorgaande enkel maar resulteren in data die van plek verandert, volgens een patroon waar de geheime sleutel niet bij van te pas komt.
3.7 Asymmetrische encryptie
3.7.1 Het probleem met symmetrische encryptie
Wat als je bij symmetrische encryptie met meerdere mensen wilt communiceren zonder dat iedereen elkaars berichten kan zien? Bob kan onmogelijk dezelfde sleutel gebruiken om met Alfredo te communiceren die hij al gebruikte met Alice. Kortom, je hebt per eindpunt een aparte sleutel nodig. Het aantal sleutels dat je nodig hebt, zeker als ook alle gebruikers onderling nog eens willen communiceren wordt snel erg groot. Je kan het aantal benodigde sleutels berekenen met de formule \(n * \frac{(n - 1)}{2}\), waarbij n het aantal gebruikers voorstelt:
- 6 gebruikers vereisen 15 sleutels.
- 7 gebruikers vereisen 21 sleutels.
- 10 gebruikers vereisen er al 45.
- 100 gebruikers vereisen er 4950!
Symmetrische encryptie heeft dus een key distribution problem wanneer er encryptie op een grote schaal nodig is. Zeker als we spreken over online communicatie, over het Internet, wordt de schaal ogenblikkelijk gigantisch groot en wordt het sleutelmanagement problematisch. Een andere oplossing is dus aan de orde.
3.7.2 Publieke cryptografie
Publieke crypto oftewel asymmetrische encryptie zal het probleem met symmetrische encryptie oplossen doordat er gebruikt wordt gemaakt van twee sleutels:
- Eén publieke sleutel.
- Eén private sleutel.
Iedereen kan de publieke sleutel gebruiken om versleutelde berichten naar de eigenaar te sturen. Enkel de eigenaar van de bijhorende private sleutel kan deze berichten echter decrypteren. Kortom, we lossen nu een deel van het sleutelprobleem op: iedereen heeft z’n eigen private sleutel (en moet deze geheim houden!) en kan via z’n publieke sleutel berichten ontvangen.
Het concept van publieke cryptografie werd in 1976 gepubliceerd door Diffie en Hellman en had een grote impact op de manier waarop beveiligde communicatie op het Internet mogelijk werd. Hun eigen artikel beschreef meteen een sleuteluitwisselingsprotocol (Diffie-Hellman, zie verder); het eerste volwaardige asymmetrische encryptie-algoritme (RSA) volgde een jaar later, in 1977.
Je kan publieke encryptie beschouwen als volgt: de publieke sleutel, die niet geheim is, is een openstaande kist. Iedereen kan de kist gebruiken om een geheime boodschap in te plaatsen en vervolgens deze op slot te klikken (encrypteren). Enkel de eigenaar van deze kist heeft de bijpassende private sleutel die echter deze kist kan opendoen en de originele boodschap kan lezen (decrypteren).
Enkele van de bekendere publieke cryptosystemen zijn onder andere RSA, DSS en El Gamal.
3.7.3 Drie toepassingen van publieke cryptografie
Publieke cryptografie wordt in de praktijk voor drie doeleinden ingezet:
- Asymmetrische encryptie (bv. RSA): berichten versleutelen met de publieke sleutel van de ontvanger, die ze enkel met zijn private sleutel kan lezen.
- Sleuteluitwisseling (key exchange, bv. Diffie-Hellman): twee partijen spreken over een onveilig kanaal een gemeenschappelijke symmetrische sleutel af, die daarna voor snellere symmetrische encryptie wordt gebruikt.
- Digitale handtekeningen: met de private sleutel wordt een bericht “getekend”, en iedereen kan met de bijhorende publieke sleutel verifiëren dat het bericht effectief van die persoon afkomstig is en onderweg niet werd aangepast.
Die laatste toepassing is een erg nuttige extra eigenschap: daar enkel de ondertekenaar de private sleutel in z’n bezit heeft, levert een geldige handtekening tegelijk authenticatie (de verzender is wie hij beweert te zijn) én integriteit (het bericht is onderweg niet gewijzigd).
In wat volgt werken we deze drie toepassingen één voor één uit, te beginnen met sleuteluitwisseling.
3.7.4 Diffie-Hellman sleuteluitwisseling
We starten met sleuteluitwisseling, omdat dit concept mooi illustreert hoe publieke crypto in de praktijk wordt gebruikt.
Het is namelijk zo dat symmetrische crypto sneller is én dus voor (realtime) communicatie interessanter is. We weten echter dat het sleutelmanagement bij symmetrische crypto een probleem is als we met grote groepen gebruikers zitten. Het Diffie-Hellman sleuteluitwisselingsconcept helpt ons hierbij: het laat toe dat twee gebruikers over een onveilig kanaal op een veilige manier een gemeenschappelijk geheim (shared secret) afspreken.
Belangrijk om meteen mee te geven: de waarden die Bob en Alice bij Diffie-Hellman gebruiken zijn sessie-specifiek (ephemeral) en worden na de uitwisseling weggegooid. Ze zijn dus niet hetzelfde als een langdurig publiek/privaat sleutelpaar zoals bij RSA — DH dient louter om een gemeenschappelijke symmetrische sleutel af te spreken, niet om berichten rechtstreeks te versleutelen.
Voor de eigenlijke uitwisseling start, spreken Alice en Bob eerst twee publieke parameters af: een (groot) priemgetal \(p\) dat als modulus dient, en een basis \(g\) (ook wel generator genoemd), kleiner dan \(p\). Deze twee waarden mogen over een onveilig kanaal worden uitgewisseld — een eventuele afluisteraar mag ze gerust kennen, dat is geen probleem voor de veiligheid. In het rekenvoorbeeld hieronder gebruiken we \(g = 7\) en \(p = 11\).
Zowel Bob als Alice kiezen vervolgens elk een geheime waarde die ze enkel voor deze sessie gebruiken. Op basis van deze geheime waarde berekenen ze elk een publieke waarde (via de formule \(g^{geheim} \bmod p\)) die ze naar de ander sturen (wat kan over een onbeveiligd kanaal). De ontvanger zal deze publieke waarde combineren met de eigen geheime waarde wat zal resulteren in een shared secret dat beiden nu kennen en kunnen gebruiken, bijvoorbeeld als de symmetrische sleutel om verdere communicatie te beveiligen.
De reden dat dit werkt, is met dank aan de modulo operator en de eigenschappen ervan. Een voorbeeld (met \(g = 7\) en \(p = 11\)):
| Stap | Alice | Bob |
|---|---|---|
| 1 | Alice kiest een geheim getal A. Ze kiest A= 3 | Bob kiest ook een geheim getal B = 6. |
| 2 | Alice berekent \(7^A \bmod 11 = 343 \bmod 11 = 2\), genaamd X. | Bob berekent \(7^B \bmod 11 = 117649 \bmod 11 = 4\), genaamd Y. |
| 3 | Alice stuurt X=2 naar Bob | Bob stuurt Y=4 naar Alice. |
| 4 | Alice berekent \(Y^A \bmod 11 = 4^3 \bmod 11 = 9\). | Bob berekent \(X^B \bmod 11 = 2^6 \bmod 11 = 9\). |
Zoals je merkt kunnen nu Alice en Bob het berekende getal 9 als gedeeld geheim gebruiken. Enkel zij kennen dit getal.
Uiteraard zullen in de praktijk Bob en Alice véél grotere getallen kiezen dan 3 en 6.
Dat Bob en Alice de waarden X en Y naar elkaar kunnen sturen is dankzij de eigenschappen van de modulo-berekening. X en Y kunnen het resultaat zijn van een gigantische hoeveelheid berekeningen en een stroper zal dus veel rekenwerk nodig hebben om alle mogelijkheden te testen.
Je kan Diffie-Hellman visueel begrijpen via verfkleuren:
- Alice en Bob spreken publiek een gemeenschappelijke startkleur af (bijvoorbeeld geel).
- Elk kiest daarnaast een geheime kleur die nooit gedeeld wordt (bijvoorbeeld Alice oranje, Bob turquoise).
- Beiden mengen hun geheime kleur met de gemeenschappelijke kleur en sturen het mengsel naar de andere partij. Een stroper kan de mengsels onderweg zien, maar kan ze niet ontleden in de originele kleuren.
- Alice voegt haar geheime kleur toe aan Bobs mengsel; Bob doet hetzelfde met het mengsel van Alice.
- Beiden komen uit op exact dezelfde eindkleur: het gedeeld geheim.
Het principe berust erop dat mengen makkelijk is, maar ontmengen praktisch onmogelijk. In de digitale versie vervult de modulo-berekening die rol.
3.7.5 RSA
Eén van de oudste, maar nog steeds populairste, publieke cryptosystemen is het in 1977 ontwikkelde RSA algoritme. RSA, wat staat voor de achternamen van de drie ontwikkelaars (Rivest, Shamir en Adleman) gebruikt sleutels van 1536 tot 4096 bits lang. Het systeem is vrij traag maar heeft als voordeel dat het veilige sleuteltransmissie toestaat over een onveilig kanaal: we zien daarom vaak RSA gebruikt worden om eerst sessiesleutels uit te wisselen, vervolgens wordt overgeschakeld op een sneller symmetrisch cipher.
De exacte berekeningen die gebeuren tijdens encryptie en decryptie leiden ons iets te ver, maar volgend voorbeeld toont een vereenvoudigde wijze waarop RSA wordt toegepast:
Data encrypteren met behulp van asymmetrische versleuteling gebeurt op bijna dezelfde wijze als de Diffie-Hellman sleutel uitwisseling. Ook nu zullen beide zijden rekenen op de eigenschappen van de modulo-operator om over een onveilig kanaal veilige communicatie te kunnen doen.
Eerst dient een publieke sleutel aangemaakt te worden:
- Hiertoe dient Bob twee grote priemgetallen,
qenpte kiezen, bijvoorbeeldp=17enq=11. - Vervolgens berekent Bob
Ndoor deze priemgetallen met elkaar te vermenigvuldigen (p*qgeeft 17 * 11,N=187). - Bob kiest nu nog een priemgetal
e, bijvoorbeeld7. - Bob kan nu zijn eigen geheime, private sleutel
dmaken, zodat geldt: \(e \cdot d \equiv 1 \pmod{(p-1)(q-1)}\). In dit voorbeeld wordt dat \(7 \cdot d \equiv 1 \pmod{16 \cdot 10}\), oftewel \(7 \cdot d \equiv 1 \pmod{160}\). - Om
dte vinden zoeken we dus een getal zodat \(7 \cdot d \bmod 160 = 1\). De mogelijke waarden voor \(7 \cdot d\) zijn bijgevolg \(1, 161, 321, \dots\). Met \(7 \cdot 23 = 161\) klopt het:d=23.
Om \(d\) te berekenen maken we gebruik van de zogenaamde Uitgebreid Euclidisch algoritme, een eeuwenoud algoritme gebaseerd op het Algoritme van Euclides dat we in het lager leerden gebruiken om de grootste gemene deler te berekenen van twee getallen.
Bob heeft dus nu:
- Publieke sleutel bestaande uit \(N=187\) en \(e=7\).
- Private sleutel \(d=23\).
Iedereen die nu naar Bob iets wilt sturen, kan dit via z’n publieke sleutel (N en e).
Stel dat Alice het ASCII-karakter X naar Bob wil sturen:
- De ASCII-waarde van X is 88.
- De encryptie door Alice gebeurt dan als volgt: \(C = \text{data}^e \bmod N\).
- De te versturen ciphertext C wordt dus: \(88^7 \bmod 187\) oftewel
C=11.
Enkel Bob zal deze ciphertext met zijn private sleutel d kunnen decrypteren door \(C^d \bmod N\) te doen, oftewel \(11^{23} \bmod 187\) wat terug de plaintext 88 geeft!
De sterkte van publieke crypto stoelt dus op het feit dat ontbinden van (grote) getallen in factoren computationeel veel moeilijker is dan de omgekeerde stap, namelijk twee getallen met elkaar vermenigvuldigen.
15621 in z’n factoren ontbinden is veel moeilijker dan de getallen 123 en 127 vermenigvuldigen (wat dus ook 15621 zal geven).
Zonder in detail te treden hoe cryptocoins en blockchains werken, is het nuttig om te vermelden dat bij cryptocoins ook de public crypto concepten worden gebruikt. Ook hier is je private sleutel uiterst belangrijk: enkel de eigenaar van de private sleutel “bezit” de bijhorende cryptocoins in de blockchain. Daarom is het belangrijk dat je NOOIT je private sleutel aan derden geeft, want zo geef je hen toegang tot jouw coins en kunnen ze vervolgens deze stelen door de private sleutel te vervangen.
3.7.6 Elliptic Curve Cryptografie (ECC)
RSA baseert zich op de moeilijkheid van het ontbinden van grote getallen in priemfactoren. Elliptic Curve Cryptografie (ECC) is een modernere vorm van asymmetrische crypto die zich baseert op de wiskundige eigenschappen van elliptische krommen over eindige velden. Het onderliggende wiskundige probleem — het Elliptic Curve Discrete Logarithm Problem (ECDLP) — is nóg moeilijker op te lossen dan factorisatie, waardoor ECC met veel kleinere sleutels hetzelfde beveiligingsniveau kan bieden als RSA:
| ECC sleutellengte | RSA equivalent | Beveiligingsniveau |
|---|---|---|
| 256 bits | 3072 bits | 128 bits |
| 384 bits | 7680 bits | 192 bits |
Het beveiligingsniveau (security strength) drukt uit hoeveel rekenwerk een aanvaller nodig heeft om de encryptie te kraken, uitgedrukt in bits. Een beveiligingsniveau van 128 bits betekent dat een aanvaller \(2^{128}\) bewerkingen moet uitvoeren — evenveel als nodig is om een symmetrische sleutel van 128 bits (zoals AES-128) te bruteforcen. Zo kunnen we de sterkte van verschillende cryptosystemen met elkaar vergelijken: een ECC-sleutel van 256 bits en een RSA-sleutel van 3072 bits zijn dus even moeilijk te kraken.
Kleinere sleutels betekenen snellere berekeningen, minder dataverkeer en lager energieverbruik. Dat maakt ECC bijzonder geschikt voor toepassingen waar rekenkracht of bandbreedte beperkt is, zoals mobiele toestellen en IoT-apparaten.
ECC wordt vandaag breed ingezet. De twee belangrijkste toepassingen zijn:
- ECDH (Elliptic Curve Diffie-Hellman): een variant van de eerder besproken Diffie-Hellman sleuteluitwisseling, maar dan gebaseerd op elliptische krommen.
- ECDSA (Elliptic Curve Digital Signature Algorithm): een digitaal handtekening-algoritme dat onder andere door Bitcoin en andere blockchains wordt gebruikt.
Moderne TLS-verbindingen (en dus HTTPS) gebruiken vrijwel altijd ECC-gebaseerde algoritmes voor de sleuteluitwisseling, omdat ze sneller en veiliger zijn dan klassiek RSA bij vergelijkbare sleutellengtes.
Net als RSA is ook ECC kwetsbaar voor toekomstige quantumcomputers. Daarom wordt er actief gewerkt aan zogenaamde post-quantum cryptografie: nieuwe algoritmes die bestand zijn tegen aanvallen met quantumcomputers. In 2024 publiceerde NIST de eerste standaarden hiervoor.
3.7.7 Intermezzo: Hashes
Voor we de digitale handtekeningen uitwerken, slaan we even een zijtak in om het concept “hash” te bespreken. Een hash is een concept uit de informatica dat we gebruiken om te controleren of een digitaal stuk tekst werd aangepast of niet. Door de tekst in een hashfuntie te steken wordt een hash aangemaakt. Deze hash is een stuk code met een vaste lengte, ongeacht de originele input. Wanneer 1 bit of meer wordt aangepast in de originele boodschap dan zal deze in een totaal andere hash resulteren. Enkel dus wanneer een identiek stuk tekst als invoer (tot op bitniveau identiek) wordt gebruikt, zullen twee hashes gelijk zijn.
Voorgaande is uiteraard onmogelijk: daar een hash meestal veel korter is dan de originele boodschap, is het mathematisch mogelijk dat twee totaal verschillende teksten toch dezelfde hash geven. Het is de opdracht van een goede hashfunctie om dit soort hash collisions zo klein mogelijk te houden.
Een hashfunctie is niet omkeerbaar: men mag onmogelijk aan de hand van een hash (ook wel digest of hashcode genoemd) terug de originele tekst kunnen achterhalen. Een hashfunctie is dus een eenrichtingsfunctie, ook wel afbeelding genoemd in wiskundige termen.
Er bestaan veel verschillende hashfuncties. Enkele van de bekendere zijn:
- MD5, oftewel Message Digest 5: deze zal een 128-bit hashwaarde genereren.
- SHA-X, oftewel Secure Hash Algorithms. Zo is er SHA-256 wat een 256 bits hash zal genereren.
De sterkte van een hash algoritme zit hem in de grootte van de kans waarop hash collisions kunnen optreden. Zo zijn er bij MD5 al veel meer collisions gevonden dan bijvoorbeeld bij het recenter gepubliceerde SHA3-512 algoritme.
Een digitale hash is dus een ideaal middel om boodschappen digitaal te ondertekenen.
3.7.8 Boodschappen ondertekenen
Een probleem bij online communicatie is dat we geen zekerheid hebben dat het ontvangen bericht wel degelijk van de persoon komt van wie we verwachtten dat deze het bericht had opgesteld. We kunnen daarom het publieke crypto systeem gebruiken om berichten te ondertekenen. Daar enkel Bob de bijhorende private sleutel kan hebben die bij z’n publieke sleutel hoort, is het bezit van deze private sleutel hebben het bewijs dat hij de rechtmatige eigenaar van een bepaalde publieke sleutel is.
Onder andere RSA laat toe om een digitale handtekening (digital signature) te plaatsen bij een bericht om zo te bewijzen dat de verzender de rechtmatige eigenaar van een bijhorende publieke sleutel is.
Een digitale handtekening wordt als extra bericht achteraan de te versturen boodschap geplaatst. De signature is als het ware een hash berekend aan de hand van de private sleutel. De ontvanger zal nu met de bijhorende publieke sleutel van de verzender kunnen verifiëren of de bijhorende private sleutel werd gebruikt om de handtekening te genereren.
Om een digitale handtekening te berekenen moeten we eerst een hash van het bericht berekenen. We gebruiken hier bijvoorbeeld MD5 of één van de SHA-algoritmes voor. Deze hash gaan we nu “verpakken” met de private sleutel.
Stel dat de berekende hash van ons bericht de waarde 35 heeft (in werkelijkheid is een hash veel langer, maar voor dit voorbeeld houden we het klein) en we beschikken over volgend sleutelpaar (bron):
- publieke sleutel: \(e=5\) en \(n=91\).
- private sleutel: \(d=29\).
De handtekening wordt berekend door de hash te versleutelen met de private sleutel: \(s = m^d \bmod n\), oftewel \(s = 35^{29} \bmod 91 = 42\).
We versturen naar de ontvanger dus de boodschap zelf én de bijhorende handtekening 42.
De ontvanger kan nu controleren of de boodschap klopt. Hij berekent eerst zelf de hash van het ontvangen bericht. Vervolgens “ontsleutelt” hij de handtekening met de publieke sleutel van de verzender door \(s^e \bmod n\) te berekenen, oftewel \(42^5 \bmod 91 = 35\). Als de zelf berekende hash gelijk is aan dit resultaat, dan weet de ontvanger dat het bericht afkomstig is van de verwachte verzender én onderweg niet werd aangepast.
3.7.8.1 Het probleem met digitale handtekeningen
We hebben echter een probleem. Hoe weet je eigenlijk dat je wel de juiste publieke sleutel gebruikt? Publieke sleutels zijn, wel, publiek. Iedereen kan jou een publieke sleutel geven en zeggen “Dit is de sleutel van persoon X” zonder dat jij kan controleren of dat zo is.
We kunnen daarom als kwaadwillig persoon bijvoorbeeld een legaal bericht onderscheppen, aanpassen en dan vervolgens ondertekenen met onze eigen handtekening. Als we vervolgens aan de ontvanger kunnen wijsmaken dat jouw publieke sleutel zogezegd bij de originele verzender hoort, dan zal de ontvanger jouw aangepaste bericht “geloven”.
Kortom, we hebben een manier nodig om de identiteit van de eigenaar van een publieke sleutel te verifiëren. Kom binnen: certificaten.
3.8 Digitale certificaten
Een certificaat is een (digitaal) document dat de identiteit van een gebruiker bindt aan een publieke sleutel. Dit document werd digitaal ondertekend door een vertrouwde derde partij (trusted third party) zodat bij twijfel van de echtheid van het certificaat men altijd bij deze derde partij terecht kan. Uiteraard is het belangrijk dat we deze derde partij kunnen vertrouwen, anders kunnen we ook niet het certificaat vertrouwen die zij onderschrijven.
Certificaten worden beschreven in de X.509 standaard.
Om een certificaat aan te maken dient Bob naar een Registration authority (RA) te gaan die zijn identiteit zal verifiëren. Dit gebeurt aan de hand van de typische documenten die ook buiten het Internet worden gebruikt om iemands identiteit te bewijzen: identiteitskaart, paspoort, rijbewijs, etc. In sommige gevallen zal de RA zelfs eisen dat Bob zich naar een fysiek kantoor begeeft om daar z’n identiteit in the flesh te bewijzen. Indien de RA de identiteit heeft bevestigd zal deze de aanvraag van Bob doorsturen naar een Certification authority (CA), inclusief Bobs publieke sleutel, die een certificaat zal aanmaken én ondertekenen.
Het gehele systeem van CA’s, RA’s, etc. dat bestaat om certificaten uit te geven, beheren en bewijzen heet een Public Key Infrastructure (PKI).
De CA zal deze informatie gebruiken om een certificaat, van een bepaalde levensduur, te genereren. Hierbij zal de echtheid van het certificaat achteraf bewezen kunnen worden door de CA:
- Het certificaat bevat Bobs publieke sleutel en informatie over Bob en de CA in leesbare vorm. Daaraan wordt een digitale handtekening van de CA toegevoegd: een hash van al deze informatie, versleuteld met de private sleutel van de CA.
- Om later de echtheid van het certificaat te verifiëren, berekent de ontvanger zelf de hash van de inhoud van het certificaat en vergelijkt die met de ontsleutelde handtekening (die met de publieke sleutel van de CA wordt gedecrypteerd). Als beide hashes gelijk zijn, weten we dat het certificaat door de gegeven CA werd ondertekend — enkel de houder van de private sleutel van die CA kan zo’n geldige handtekening produceren.
Een X.509-certificaat bevat minstens volgende velden:
- Versie van de X.509-standaard (vandaag doorgaans v3).
- Serienummer: uniek binnen de uitgevende CA.
- Signature algorithm: welk algoritme de CA gebruikte om te ondertekenen (bv. SHA-256 met RSA).
- Issuer: naam van de CA die het certificaat uitgaf.
- Validity: begin- en einddatum van geldigheid.
- Subject: naam van de eigenaar (domeinnaam of persoon).
- Public key van de eigenaar, met het gebruikte algoritme.
- Extensions: bijkomende info zoals gebruiksbeperkingen of alternatieve domeinnamen.
- Signature: de digitale handtekening van de CA over al het bovenstaande.
Voorgaande proces zal bijvoorbeeld plaatsvinden wanneer je browser via een HTTPS verbinding surft naar een website en zo wil controleren of wel degelijk met de website wordt gecommuniceerd en niet met een imposter. Indien de browser (of de gebruiker) twijfelt aan de echtheid van de publieke sleutel van de CA die het certificaat van de website ondertekent, dan zal het voorgaande proces zich herhalen, maar deze keer om het certificaat van de CA te controleren met behulp van een bovenliggende CA. Op die manier kan het dus zijn dat een keten van CA’s ontstaan die telkens CA’s onder zich bewijzen. Uiteraard zal er steeds bovenaan zo’n ketting een root CA staan. Als je die vertrouwt, dan kan je al de CA’s er onder dus ook vertrouwen…maar ook vice versa!
Alhoewel HTTPS al sinds 1995 bestond, werd het tot voor kort amper door websites aangeboden. Nochtans geeft HTTPS een extra defensielaag tijdens de communicatie van jouw computer met die waar een website op gehost staat. HTTPS zal namelijk je communicatie versleutelen zodat enkel zender en ontvanger kunnen lezen wat er gezegd wordt. Met HTTP is dat niet: al je communicatie kan door eender wie gelezen worden die zich tussen jouw computer en je eindbestemming nestelt. Het helpt echter niet dat je data versleuteld wordt als je niet kan bevestigen dat de ontvangende website ook effectief diegene is die je nodig hebt, vandaar dat dus certificaten en HTTPS in tandem werken om gebruikers een veiliger Internet aan te bieden.
Pas in 2017 boden meer dan de helft van de websites wereldwijd HTTPS aan. In 2021 gebruikt ongeveer 70% van alle websites HTTPS als standaard communicatiemiddel aan (vroeger waren er al websites met HTTPS, maar HTTP was de standaard oplossing).
Het ergste dat voor een CA kan voorvallen is dat de betrouwbaarheid van de CA in het gedrang komt. Als een CA bijvoorbeeld weet heeft van een potentiële inbraak op zijn systemen dan bestaat er de kans dat aanvallers de private sleutel van de CA hebben bemachtigd en dus zelf certificaten op naam van de CA kunnen genereren, met alle gevolgen van dien! Indien dus deze kans bestaat, is er een breach of trust en zullen alle certificaten van deze CA als ongeldig worden bestempeld, inclusief alle certificaten van sub-CA’s! Dit kan verregaande gevolgen hebben.
In 2011 werd de Nederlandse CA DigiNotar gehackt. De aanvallers konden valse certificaten uitgeven voor onder andere google.com, die vervolgens werden ingezet om Iraanse Gmail-gebruikers te bespioneren. Zodra de inbraak publiek werd, verwijderden browserfabrikanten DigiNotar uit hun lijst van vertrouwde root-CA’s. Alle certificaten van DigiNotar werden daarmee in één klap ongeldig — ook die van de Nederlandse overheid, die DigiNotar gebruikte voor DigiD en andere diensten. DigiNotar zelf ging binnen enkele weken failliet. Het incident toont hoe fragiel de chain of trust is: één gecompromitteerde CA kan het vertrouwen voor duizenden sites kapotmaken.
3.8.1 Certificaten bekijken
In iedere moderne browser kan je snel bekijken hoe zo’n certificaat er juist uitziet. Als je via een HTTPS verbinding naar een website surft, dan op het slotje naast de URL in de adresbalk klikt kan je doorklikken om het certificaat te openen. Als je naar HTTPS://www.belgium.be surft en dit doet dan krijg je eerst wat samenvattende informatie:
Zo zien we onder andere de geldigheidsduur, alsook de CA die dit certificaat heeft gegenereerd. Onder details kunnen we onder andere de publieke sleutel zien van de website alsook de gebruikte algoritmes voor de hash, e.d.
En op de laatste tab, Certificeringspad, zien we de chain of trust. We kunnen vervolgens hier de bovenliggende certificaten bekijken.
Het certificaat van Sectigo is uiteraard een selfsigned certificate, daar zij “bovenaan de hiërarchie staan”. Als we Sectigo niet vertrouwen dan kunnen we ook de communicatie met belgium.be niet vertrouwen.
3.8.2 Persoonlijke certificaten
Naast certificaten voor webservers (zogenaamde SSL certificaten) kan je ook een persoonlijk certificaat aankopen om je eigen identiteit aan derden te bewijzen tijdens bijvoorbeeld e-mail-communicatie. Voorts heb je ook code signing certificaten die de echtheid van een applicatie bewijzen zodat je zeker bent dat je geen malware installeert als je programma X hebt gedownload.
Persoonlijke certificaten worden ook gebruikt voor mutual TLS (mTLS), een uitbreiding op gewone HTTPS waarbij niet alleen de server, maar ook de client zich met een certificaat authenticeert. Dit wordt vaak gebruikt in bankomgevingen, e-government, bedrijfs-VPN’s en communicatie tussen backend-servers, waar de server zeker wil zijn dat de client effectief is wie die beweert te zijn. Bij gewone HTTPS gebeurt dit niet omdat een website in principe elke bezoeker welkom heet.
Als je in Windows 10 of nieuwer een applicatie of installer probeert uit te voeren dan zal de ingebouwde SmartScreen service ogenblikkelijk de echtheid (of ontbreken van) het certificaat controleren, net zoals dit ook in de browser zou gebeuren.
Wil dat dan zeggen dat je applicaties niet kunt vertrouwen die door Smart Screen als onveilig worden aangeduid? Neen, dat niet. Je mag niet vergeten dat een certificaat geld kost en dat niet alle software-ontwikkelaars de middelen hebben om een officieel certificaat te kopen. Het loont dus altijd om extra waakzaam te zijn wanneer Smart Screen een waarschuwing geeft, maar het is dus niet zo dat de software automatisch als onveilig moet gehanteerd worden.
3.8.3 Web of Trust: een alternatief voor PKI
Het PKI-model steunt op gecentraliseerde Certificate Authorities die de identiteit van sleuteleigenaars garanderen. Er bestaat echter ook een gedecentraliseerd alternatief: het Web of Trust (WoT), dat bekend werd door PGP (Pretty Good Privacy) en de open-source variant GPG (GNU Privacy Guard).
In een Web of Trust zijn er geen centrale autoriteiten. In plaats daarvan ondertekenen gebruikers elkaars publieke sleutels. Als Alice de publieke sleutel van Bob persoonlijk heeft geverifieerd (bijvoorbeeld door zijn key fingerprint te vergelijken tijdens een ontmoeting), kan zij zijn sleutel ondertekenen met haar eigen private sleutel. Hiermee verklaart Alice: “Ik bevestig dat deze publieke sleutel effectief van Bob is.”
Stel nu dat Carol de sleutel van Bob nodig heeft maar hem niet persoonlijk kent. Als Carol wél Alice vertrouwt en ziet dat Alice de sleutel van Bob heeft ondertekend, dan kan Carol via dat vertrouwenspad besluiten om ook Bobs sleutel te aanvaarden. Zo ontstaat een netwerk — een web — van onderlinge vertrouwensrelaties.
| Eigenschap | PKI | Web of Trust |
|---|---|---|
| Vertrouwensmodel | Hiërarchisch (top-down via CA’s) | Gedecentraliseerd (peer-to-peer) |
| Wie valideert? | Certificate Authorities | De gebruikers zelf |
| Zwak punt | Eén gecompromitteerde CA treft iedereen | Vergt actieve deelname van gebruikers |
| Typisch gebruik | HTTPS, e-mail (S/MIME), code signing | PGP/GPG e-mailencryptie, softwarepakketten |
Het Web of Trust werd jarenlang gebruikt door de PGP/GPG-gemeenschap, onder andere via zogenaamde key signing parties waar mensen fysiek samenkwamen om elkaars sleutels te verifiëren en te ondertekenen. In de praktijk bleek het model echter moeilijk schaalbaar: het vergt veel moeite van individuele gebruikers en het is lastig om een betrouwbaar vertrouwenspad te vinden naar iemand die je niet kent. Daarom wordt voor de meeste toepassingen op het Internet vandaag het PKI-model met Certificate Authorities gebruikt.
3.9 HTTPS en TLS
Certificaten vormen het hart van een veilige manier van surfen. HTTPS, “HTTP-Secure”, zorgt ervoor dat de communicatie tussen je browser en de website via een beveiligde, geëncrypteerde tunnel gebeurt. Tegenwoordig is HTTPS de default manier om een website te benaderen, maar dat is maar recent. Vroeger gebeurde alles via HTTP, waardoor iedereen die jouw trafiek kon sniffen, kon zien welke informatie je met de website uitwisselde.
HTTPS is een protocol dat een beveiligde encryptietunnel opzet tussen jou en de website waarover vervolgens gewoon HTTP-verkeer kan verlopen (dit gebeurt over poort 443 in plaats van de klassieke poort 80 waarover HTTP verloopt). Deze tunnel wordt opgezet door het TLS-protocol, het Transport Layer Security protocol, dat de opvolger is van SSL (Secure Sockets Layer). TLS gebruikt certificaten om te vergewissen dat de website aan de andere zijde wel degelijk de website is die de gebruiker verwacht. Het doet dit door de publieke sleutel van de website eerst te controleren voor het vervolgens deze sleutel gebruikt om een gemeenschappelijke sleutel af te spreken die zal dienst doen als de encryptie-sleutel voor de gemeenschappelijke tunnel. Vanaf dit punt kunnen derden de trafiek van en naar de website niet meer sniffen.
Samengevat: HTTPS is de combinatie van HTTP en een veilige encryptietunnel die met behulp van het TLS protocol wordt opgezet.
Samengevat zal dus TLS twee zaken doen:
- Door middel van een certificaat (asymmetrische crypto) wordt de identiteit (de publieke sleutel) van de website gecontroleerd.
- Door middel van een afgesproken algoritme (Diffie-Hellman, Forward Secrecy, Elliptic Curve, etc.) een gemeenschappelijke sleutel(s) afspreken en uitwisselen.
Zoals reeds eerder vermeld is asymmetrische crypto trager, waardoor het altijd aanbevolen is om de trafiek tussen 2 punten finaal via een symmetrische crypto verbinding te laten plaatsvinden. TLS/HTTPS combineert met andere woorden de sterktes van beide soorten crypto om zo de zwaktes van beiden te neutraliseren.
De manier waarop een TLS-verbinding wordt opgezet is vrij uitgebreid. Volgende briljante website (tls.ulfheim.net/) visualiseert de berichten die server en client uitwisselen om zo’n verbinding te starten, onderhouden en eindigen.
Alhoewel HTTPS onze verbinding een pak veiliger maakt, heeft het voor je ISP (Internet Service Provider, bijvoorbeeld Telenet of Proximus) en de website ook enkele nadelen. Omdat alle informatie geëncrypteerd wordt heeft de ISP geen enkel idee wat voor informatie je aan het uitwisselen bent, waardoor caching ook niet meer mogelijk is. In een normale HTTP-omgeving kan een ISP trafiek over het Internet uitsparen door een reeds bewaarde versie van hetgeen jij nodig hebt uit de cache te halen en naar je te sturen. Ook de website naar waar je surft, ondervindt dit nadeel: het zal met HTTPS veel meer trafiek genereren dan wanneer de tussenliggende ISP een deel van het werk via zijn caching overnemen.
3.9.1 End-to-end encryptie onder druk: Apple en de UK
End-to-end encryptie (E2EE) zorgt ervoor dat enkel de zender en ontvanger de inhoud van berichten of data kunnen lezen — zelfs de dienstverlener (zoals Apple of Google) heeft geen toegang. Dit principe is een directe toepassing van de publieke cryptografie die we in dit hoofdstuk bespraken: data wordt versleuteld met de publieke sleutel van de ontvanger en kan enkel met diens private sleutel worden ontsleuteld.
In 2025 werd Apple door de Britse overheid gedwongen om Advanced Data Protection (ADP), de end-to-end encryptie van iCloud-data, uit te schakelen voor alle gebruikers in het Verenigd Koninkrijk. De overheid eiste namelijk een backdoor: een manier voor opsporingsdiensten om toegang te krijgen tot versleutelde gegevens. Apple weigerde een backdoor in te bouwen — omdat dit de beveiliging voor alle gebruikers zou verzwakken — en koos er in plaats daarvan voor om de E2EE-functionaliteit in het VK volledig te verwijderen. iMessage, FaceTime en iCloud Keychain behielden wel hun end-to-end encryptie.
Dit voorbeeld illustreert een fundamenteel spanningsveld in cryptografie: een backdoor die enkel voor “de goeden” werkt, bestaat niet. Zodra er een achterpoortje in een encryptiesysteem zit, is het slechts een kwestie van tijd voordat ook kwaadwillige actoren deze ontdekken of misbruiken. Dit gaat recht in tegen Kerckhoffs principe: de veiligheid van het systeem mag enkel afhangen van de geheimhouding van de sleutel, niet van het verbergen van zwakheden in het systeem zelf.
3.9.1.1 Chat Control: ook in de EU
Dit debat speelt niet enkel in het Verenigd Koninkrijk. De Europese Commissie stelde in 2022 de Child Sexual Abuse Regulation voor, beter bekend als Chat Control. Dit voorstel zou chatdiensten zoals WhatsApp en Signal verplichten om berichten van alle gebruikers automatisch te scannen op illegale inhoud — ook berichten die end-to-end versleuteld zijn. Critici, waaronder cryptografen en organisaties als de EFF en EDRi, waarschuwen dat dit technisch neerkomt op het inbouwen van een backdoor of het installeren van client-side scanning (spyware op het toestel zelf), wat de facto end-to-end encryptie onmogelijk maakt.
Na jarenlange controverse en tegenstand vanuit het Europees Parlement, werd het meest omstreden onderdeel — het verplicht scannen van versleutelde berichten — in 2025 afgezwakt. Het voorstel wordt echter nog steeds onderhandeld en de uiteindelijke impact op E2EE blijft onzeker.
De kern van het probleem is telkens hetzelfde: je kan niet tegelijk echte end-to-end encryptie garanderen én een manier voorzien om berichten te lezen. Of de sleutel is geheim, of hij is het niet — er is geen tussenweg.
3.9.2 Mitmproxy
Mitmproxy is een krachtige linux-tool die een man-in-the-middle aanval op HTTPS toelaat. Het zal ervoor zorgen dat een aanvaller zich tussen jou en het Internet kan nestelen en vervolgens doen alsof al je HTTPS-verbindingen veilig blijven. In de praktijk zorgt mitmproxy ervoor dat alle HTTPS-verbindingen van de client naar de aanvaller gebeuren, die op zijn beurt TLS tunnels zal opzetten met de website waar het slachtoffer naar surft. Hierdoor kan de aanvaller enerzijds alle trafiek lezen, maar bijvoorbeeld ook ongezien aanpassen.
De aanvaller zal echter nog steeds geen geldige certificaten kunnen genereren waardoor moderne browsers normaal gezien hier een waarschuwing zouden moeten geven.
3.10 Samenvatting
Cryptografie is de gereedschapskist waarmee we CIA realiseren. De centrale inzichten uit dit hoofdstuk:
- Kerckhoffs is de kern: alleen de sleutel moet geheim blijven, nooit het algoritme. Security through obscurity is een valstrik.
- Oude technieken (Caesar, Vigenère, scytale) combineren substitutie en transpositie — dezelfde bouwstenen die AES nog steeds gebruikt.
- Symmetrische encryptie is snel (AES als de-facto standaard, gebaseerd op het Belgische Rijndael) maar kent het sleuteloverdrachtsprobleem.
- De blockcipher-mode is even kritiek als de cipher zelf: ECB lekt patronen, CBC/CTR niet — mits correcte IV/nonce.
- Asymmetrische encryptie (RSA, ECC) lost het sleuteloverdrachtsprobleem op via een publiek/privé-sleutelpaar. Diffie-Hellman laat twee partijen zonder vooraf gedeeld geheim een gezamenlijke sleutel afspreken.
- Hashes zorgen voor integrity, digitale handtekeningen voegen daar authenticiteit en non-repudiation aan toe.
- Digitale certificaten en PKI lossen het vertrouwensprobleem op — maar enkel zolang de CA betrouwbaar blijft (cfr. de val van DigiNotar).
- HTTPS/TLS combineert al deze bouwstenen, en toch blijft het kwetsbaar zonder goede certificaatvalidatie, zoals mitmproxy aantoont.
- Cryptanalyse dwingt sleutels steeds langer te maken; quantum-computers bedreigen RSA/ECC op lange termijn — store now, decrypt later is een realistische dreiging.
In het volgende hoofdstuk zien we hoe authenticatie op deze crypto-bouwstenen steunt.











































