henk-reints.nl
Pagina voor het laatst geupdated:
basisbeginselen van Ofwel: hoe houd ik een geheim geheim geheim? De kernvraag van moderne encryptie is eigenlijk: Hoe kun je een vertrouwelijke, geheime boodschap naar iemand zenden via een niet-beveiligd communicatiekanaal? Wel, in principe is dat vrij simpel: je moet de data zodaning "verminken" dat het onleesbaar wordt, maar wel zo, dat de legitieme ontvanger het weer kan terugvertalen naar het oorspronkelijke bericht. En verder niemand.
Inhoudsopgave
Letterverwisseling
Stel vervolgens dat we met de legitieme ontvanger de volgende vertaaltabel hebben afgesproken. N.B. deze tabel moet je dus wel op een beveiligde manier uitwisselen met de beoogde ontvanger!
N.B. deze tabel is met JavaScript naar willekeur bepaald, Dan kunnen we de geheime boodschap als volgt vertalen:
Mensen die de vertaaltabel niet kennen weten hier dus geen raad mee!
Ontcijferen op basis van statistiek
Wat betreft de "e" klopt dit dus al met het Nederlands! De letterfrequenties van de gecodeerde tekst zijn:
Zodat we dus al meteen kunnen veronderstellen dat we de kunnen terugvertalen naar de "e"! Voor een korte tekst als deze zullen niet alle letterfrequenties kloppen met de statistiek (in het Nederlands komt b.v. de "n" op de tweede plaats, terwijl dat in dit voorbeeld niet het geval is), maar voor een lange tekst kom je een heel eind. Zonder de oorspronkelijke vertaaltabel dus!
Behalve letterfrequenties zijn er natuurlijk ook statistieken omtrent woordlengtes,
lettervolgordes binnen woorden, woordvolgordes binnen zinnen etc.
Gewapend met die kennis is een op deze manier gecodeerde tekst simpel te kraken,
ook zonder de vertaaltabel.
Het gecodeerde bericht bevat doodgewoon nog veel te veel herkenbare informatie.
Aangezien aldus gecodeerde berichten te kraken zijn zonder de bijbehorende sleutel (de vertaaltabel) is voor deugdelijke geheimhouding de hele methode dus onbruikbaar! Zodra iemand (met name de vijand!) het trucje kent is de hele methode waardeloos.
Tekst omzetten naar getallen
Zoals je ziet zijn de cijfers en de letters er keurig op de juiste volgorde in opgenomen, zodat je b.v tekst kunt sorteren op basis van deze getalwaarden! Voor de getallen 128 t/m 255 (255 is het grootste getal dat in een byte past) waren vroeger geen tekens gedefinieerd, maar tegenwoordig staan daar met name de letters met diacritische tekens, zoals bv. á, é, ë, ö, etc. Een en ander betekent, dat een tekst die in de computer is ingebracht altijd is te beschouwen als een gewone serie getallen, waarbij elk getal in het bereik van 0 t/m 255 valt. Onze geheime boodschap wordt derhalve in het geheugen van de computer opgeslagen als de volgende serie getallen:
Willekeur inbouwen
1) we kunnen het resultaat niet meer in een byte opslaan; 2) we voegen informatie toe! Een afluisteraar weet dan immers dat voor die letter de getalwaarde plus de sleutel groter is dan 255, waarmee het aantal uit te proberen mogelijkheden voor hem wordt gehalveerd. En het laatste wat we willen is afluisteraars in de kaart spelen! Omdat de serie getallen lang is, kunnen we er een tekst tot die lengte mee coderen. Dus, om een begin te maken voor het eerste stukje van onze geheime boodschap:
Zoals je ziet, wordt nu dezelfde letter (bijvoorbeeld de "e") telkens naar een andere waarde omgezet (nou ja, af en toe kan er natuurlijk best een keer hetzelfde uitkomen, oké). De afluisteraar kan dus met zijn statistische kennis van de Nederlandse taal niet veel meer beginnen! Als we het aldus versleutelde bericht in zijn geheel volgens de ASCII-tabel terugvertalen naar gewone tekens wordt het:
Om eerlijk te zijn: ik heb enkele codes moeten aanpassen omdat je browser er anders geen raad mee weet. Er zijn in de versleutelde boodschap immers getallen ontstaan die op willekeurige plekken in de ASCII-tabel staan, en die zogenoemde onprintbare codes heb ik allemaal vertaald naar het "" teken. En hoe decodeer je dat? Wel, natuurlijk moet je dan per getal van de versleutelde boodschap het zoveelste getal van de sleutel er weer aftrekken. Kom je daarbij onder de nul, dan tel je er 256 bij op (dit compenseert dus het speciale wat we bij het optellen gedaan hebben). In plaats van het optellen en aftrekken is er nog een andere bewerking mogelijk, die in de computer veel handiger is, omdat het zijn eigen 'inverse bewerking' is. Dat is de zogenoemde XOR operator, ofwel "exclusive OR". Deze XOR werkt op de afzonderlijke bitjes in een getal (de eentjes en de nulletjes zoals het feitelijk in de computer staat) en geeft aan of twee zulke bitjes wel of niet verschillend zijn. Het leuke is dat we de oorspronkelijke waarde terugkrijgen als we hem twee maal met hetzelfde XOR-en! Zie de volgende tabel, waarin a en b de betreffende bitjes zijn. Met c = a XOR b en d = c XOR b ofwel d = (a XOR b) XOR b zie je dat d weer gelijk is aan a.
In de praktijk zullen we dan ook de XOR gebruiken, omdat dan het versleutelen en het ontsleutelen met precies dezelfde methode gedaan kan worden! Die serie sleutelgetallen moeten we nu dus angstvallig geheimhouden! Alleen de legitieme ontvanger mag er een kopie van hebben. Als nu een afluisteraar de methode ontdekt: gefeliciteerd, maar zonder de serie sleutelgetallen heeft ie daar niets aan. Zonder de sleutelgetallen kan dit niet worden gekraakt, mits de serie sleutelgetallen goed is opgebouwd. De sleutelgetallen moeten zich gedragen als ruis, willekeurige getallen die door toeval zijn ontstaan, zonder dat er een patroon in te herkennen is. Dan is aan de versleutelde boodschap ook weinig tot niets te herkennen.
Schijnbaar willekeurige getallen genereren Wat we zouden willen, is een eenvoudige manier om een onbeperkte serie schijnbaar willekeurige getallen te produceren op basis van een korte geheime code (een wachtwoord). Schijnbaar willekeurig, omdat het namelijk wel degelijk zo in elkaar moet zitten dat je dezelfde serie kunt reproduceren, anders is de boodschap immers niet meer te ontsleutelen. In het Engels heet zo iets een Pseudo Random Number Generator, vaak afgekort als PRNG. Laten we maar eens kijken of we er eentje kunnen maken. Een digitale dobbelsteen. We gaan een heel simpele PRNG maken, eentje die voortdurend getallen van 1 t/m 6 "uitspuugt", in een min of meer willekeurig patroon. Daarvoor beginnen we met wat we de interne status van de PRNG zullen noemen. Gewoon de getallen 1 t/m 6 in een willekeurige volgorde:
Ververs de pagina en je krijgt een andere status! We gaan gebruik maken van het feit dat de getallen die in de status staan, ook kunnen worden gebruikt als een index naar een positie in diezelfde status! We gebruiken ook nog twee losse indices, die we i en j zullen noemen, alsmede een hulpindex k. De indices i en j initialiseren we op de waarde 1. Dan gaan we het volgende proces steeds herhalen:
Als we met dat proces doorgaan totdat we er 100 hebben wordt dat de volgende serie:
En nu kun je het wellicht al raden: die allereerste status is het enige wat we hoeven te onthouden om de hele serie te reproduceren! En een andere beginstatus levert een compleet andere serie op. Probeer dat maar eens, gewoon deze pagina verversen levert al een andere beginstatus en dus een andere serie. En als je die initiële status goed geheim houdt, blijft de hele serie geheim! Die initiële status is dus eigenlijk het wachtwoord! En nu is dit, met slechts 6 getallen, natuurlijk niet de allerbeste PRNG die we kunnen maken, omdat er maar een beperkt aantal mogelijkheden zijn voor de status. Daardoor is een op basis hiervan versleutelde boodschap met een snelle computer toch in korte tijd te kraken. Gewoon alle mogelijkheden uitproberen zal waarschijnlijk in slechts één geval iets leesbaars opleveren en dat moet dan het oorspronkelijke bericht zijn. Bovendien gaat deze serie al vrij snel een repeterend karakter krijgen. Op een gegeven moment kom je namelijk met de status en de indices i en j weer terug op de beginsituatie en dan begint de hele serie weer gewoon opnieuw. De getallen 1 t/m 6 kunnen op slechts 6 x 5 x 4 x 3 x 2 x 1 = 720 verschillende volgordes staan en samen met de 36 mogelijke combinaties van i en j betekent dit dat er een periodiciteit is te verwachten van 36 x 720 = stappen. Maar dus toch niet slecht voor zo'n heel erg simpele PRNG! In elk geval ruim voldoende voor een spelletje mens erger je. Je kunt je ongetwijfeld wel voorstellen dat we een veel betere PRNG krijgen als we ditzelfde trucje uithalen met de getallen 0 t/m 255, en uiteraard heb ik de hierboven gebruikte voorbeeldserie daarmee gemaakt!
Praktisch onkraakbare versleuteling Ter vergelijking: de ouderdom van het heelal, sinds de "big bang", wordt geschat op ongeveer 15 miljard = 15000000000 jaar. In 1 jaar zitten ongeveer 365,25 x 24 x 60 x 60 = seconden, dus de ouderdom van het heelal is ongeveer seconden. Een computer die 1 miljoen statussen (stati?) per seconde kan uitproberen zou dus in de hele leeftijd van het heelal nu ongeveer mogelijkheden hebben uitgeprobeerd. Een getal van slechts cijfers. Die computer is dus nog laaaaang niet klaar! En als we er een miljard van zulke computers tegelijk op hadden gezet, meteen al bij de big bang, dan was het aantal uitgeprobeerde mogelijkheden op dit moment nog steeds pas een getal van slechts cijfers! Om echt alle mogelijkheden uit te proberen met dat arsenaal aan computers is het aantal benodigde jaren een getal van cijfers! Het op zichzelf heel simpele probleem van alle mogelijkheden uitproberen (een computerprogrammaatje van slechts pakweg 10 tot 20 regels code) is praktisch onoplosbaar vanwege dit gigantische aantal mogelijkheden. Ook onze afluisterende vijand zal dus onze versleutelde berichten niet zomaar even kunnen kraken. Een hele geruststelling.
Wachtwoord in plaats van tabel We doen daarvoor iets soortgelijks als tijdens het produceren van de willekeurige getallen door de PRNG, alleen mengen we er nu de ASCII-waardes van een deugdelijk wachtwoord doorheen. En in plaats van een wachtwoord mag het natuurlijk ook best een wachtzin zijn, waarom zouden we spaties en leestekens verbieden? We beginnen dan door de status gewoon 'op volgorde' te initialiseren, dus de getallen 0 t/m 255 achter elkaar. Dan gaan we minsten 256 rondes uitvoeren om die status door elkaar te gooien op basis van het wachtwoord. Zo nodig - als het een kort wachtwoord is - gaan we meerdere keren door het wachtwoord heen. En als het een heel lange wachtzin is van meer dan 256 tekens gebruiken we ze allemaal. Verder gebruiken we weer de indices i en j, en ook gebruiken we index k om tekens uit het wachtwoord te lezen. De posities starten op nul (dus b.v. de eerste letter van het wachtwoord staat op positie nul). We beginnen met i = 0, j = 0 en k = 0, en dan doen we de volgende stappen minimaal 256 keer, en vaker als het wachtwoord langer is:
Nu zijn we klaar!
We hebben alles wat we nodig hebben voor een deugdelijke,
vrijwel onkraakbare encryptie met een gemakkelijk te onthouden wachtwoord.
Want in tegenstelling tot wat ik boven heb vermeld omtrent het gebrek aan
willekeur in een normale zin, geldt die beperking voor deze methode niet.
Het wachtwoord geeft namelijk slechts de beginsituatie van een deugdelijke PRNG,
terwijl het zelf niet per se een goede pseudowillekeurige serie hoeft te zijn.
Overigens is het natuurlijk voor de geheimhouding wel beter als dat wachtwoord
een grote mate van willekeur heeft, maar dan is het wel lastiger te onthouden.
zou een behoorlijk goede wachtzin zijn. Niet te raden door wie dan ook.
Maar gewoon het koosnaampje van je geheime
Zend- en ontvangprocedure Zender:
Legitieme ontvanger:
Afluisteraar:
ARCFOUR algoritme
De kracht van de versleuteling zit hem in het vermengen van het bericht met schijnbaar willekeurige getallen. Daardoor wordt statistische informatie in het versleutelde resultaat vrijwel volledig gemaskeerd en een afluisteraar kan er dus niets mee beginnen, mits de willekeurige getallen in statistisch opzicht van voldoende kwaliteit zijn. Niet of nauwelijks van ruis te onderscheiden. De versleutelde boodschap gedraagt zich dan zelf ook als een serie willekeurige getallen. Zonder patroon. Zonder statistische kenmerken. Schijnbaar zonder informatie (maar de zender en de legitieme ontvanger weten natuurlijk wel beter...).
Er is trouwens in deze algoritme wel een zwakte ontdekt, het begin van de gegenereerde serie schijnbaar willekeurige getallen
bevat namelijk nog wel degelijk traceerbare informatie over het wachtwoord,
waardoor het onder bepaalde omstandigheden toch te kraken is.
Dit is de zogeheten Fluhrer, Mantin and Shamir attack (zie ook
RSA Security Response to Weaknesses in Key Scheduling Algorithm of RC4).
Vingerafdruk & automatische controle Wat we gaan doen is het volgende. Precies net zoals we hierboven het wachtwoord "door de mangel" hebben gehaald om een initiële status voor de PRNG te krijgen, doen we dat nu met het bericht zelf. Alleen doen we die initialisatie nu twee keer, zodat ook een heel lang bericht altijd dubbel door de mangel gaat. We gaan dan de PRNG opstarten met deze beginstatus die dus is bepaald door de te versleutelen boodschap zelf. En dan nemen we laten we zeggen de eerste 20 getallen die door die PRNG worden geproduceerd. Dat kunnen we dan als vingerafdruk gebruiken. Overigens zou het vanwege de eerder genoemde zwakte in RC4 beter zijn om dan niet nummer 1 t/m 20 te nemen maar b.v. 1001 t/m 1020, maar om der wille van de eenvoud doe ik dat op deze pagina niet. En bedenk dat deze door mij voorgestelde vingerafdruk hoofdzakelijk is bedoeld als demonstratie, voor de "echtes" zijn er veel betere. Zo'n vingerafdruk van 20 bytes met willekeurige waardes willen we nog graag wat leesbaarder maken, waarbij ik nog een beetje informatieverlies produceer, door van elke byte slechts de rest bij deling door 64 te nemen. Dan komt er een getal uit van 0 tot 63, in totaal dus 64 mogelijkheden. We gaan de volgende 64 tekens gebruiken voor de vingerafdruk:
Deze tekenset is in de internetwereld geen onbekende, het is de zogenoemde base 64
tekenset, die veel wordt gebruikt om bijlagen van e-mails te coderen, zoals bijvoorbeeld foto's.
Zo'n vingerafdruk zegt dus iets over het bericht, hij is er immers direct van afgeleid, maar toch zegt hij niets over de feitelijke inhoud van het bericht. Een ander bericht heeft een andere vingerafdruk. En het is niet zo dat twee berichten die veel op elkaar lijken ongeveer dezelfde vingerafdruk hebben. Je kunt met de vingerafdruk eigenlijk maar één ding vaststellen: het is wel of niet het goede bericht. Als twee onbekende berichten een verschillende vingerafdruk hebben zijn de berichten zeker verschillend, en als ze dezelfde vingerafdruk hebben zijn die berichten hoogstwaarschijnlijk gelijk. Hoogstwaarschijnlijk, want absolute zekerheid heb je niet, bij het bepalen van de vingerafdruk is namelijk per saldo gewoon een hoop informatie verloren gegaan. En dat willen we ook. Een vingerafdruk moet eenrichtingsverkeer zijn. Het moet onmogelijk zijn om vanuit de vingerafdruk het bericht weer terug te vinden, het was immers een geheim bericht! Maar de kans dat twee verschillende berichten dezelfde vingerafdruk hebben is wel hééééél erg klein. Verwaarloosbaar. Met een goede vingerafdruk kun je dus, zelfs als die vingerafdruk onversleuteld is, een bericht identificeren zonder daarvan de inhoud prijs te geven. Hieronder staan enkele voorbeelden van vingerafdrukken van telkens twee sterk op elkaar lijkende berichten:
We gaan nu als volgt versleutelen en ontsleutelen: Zender:
Ontvanger:
JavaScript code
Verder moet je er rekening mee houden dat in Windows een bericht ook heel speciale tekens kan bevatten, met codes groter dan 255 (Unicode heet dat). In JavaScript is een standaardfunctie beschikbaar om speciale tekens en niet printbare tekens om te zetten naar een gewone ASCII-codering. Dan wordt de interne code van een teken omgezet naar een tekstuele representatie van dat getal. Die functie heet 'escape'. En om dat weer ongedaan te maken gebruik je de 'unescape'. Het is een goede gewoonte om bij versleuteling van teksten die twee functies ook altijd te gebruiken. 'escape' bij het versleutelen en 'unescape' bij het ontsleutelen. Zowel voor het bericht zelf als voor de versleuteling. Dan krijg je de volgende code voor het ver- en ontsleutelen:
Het staat je vrij om deze code - mits ongewijzigd en MET bronvermelding - op je eigen website of waar dan ook te gebruiken!
Spelen met ARCFOUR
Tot zo ver ARCFOUR. We gaan nu eens kijken of we met vingerafdrukken en willekeurige getallen nog meer leuke dingen kunnen doen.
Client/server wachtwoordcontrole Op de server zijn dan dus gebruikersnaam+wachtwoord ergens in een bestand opgeslagen. Maar het liefst slaan we het wachtwoord natuurlijk niet leesbaar op! Als iemand het bestand te pakken zou krijgen weet hij dan immers alle wachtwoorden! Van iedereen! Dat doen we dus anders. Wat we op de server opslaan is de gebruikersnaam plus de vingerafdruk van gebruikersnaam+wachtwoord. Waarom die combinatie? Wel, stel dat we de gebruikersnaam en de vingerafdruk van alleen het wachtwoord opslaan. En stel dat hacker Jan ontdekt dat de vingerafdruk van Piet's wachtwoord gelijk is aan de vingerafdruk van zijn eigen wachtwoord? Dan weet hij dat Piet hetzelfde wachtwoord heeft als hijzelf! Dat voorkom je door de vingerafdruk op te slaan van de combinatie van gebruikersnaam en wachtwoord. Die vingerafdruk is voor Jan en Piet immers verschillend. Tegelijk is daarmee natuurlijk die vingerafdruk het eigenlijke wachtwoord geworden, dat is namelijk het enige wat de server nog kan controleren. Het blijft dus nog steeds uitermate belangrijk dat het wachtwoordenbestand op de server goed is afgeschermd, men mag het nog steeds niet zomaar kunnen lezen! Door zo'n vingerafdruk op te slaan i.p.v. het wachtwoord zelf wordt het dus alleen maar onmogelijk gemaakt om het oorspronkelijke wachtwoord te achterhalen, maar voor de feitelijke toegangsbeveiliging heeft het nog steeds geen toegevoegde waarde! En het is dus ook geen optie on die vingerafdruk "in z'n blootje" over het netwerk te gaan verzenden... Hoe kunnen we dan toch aan de server laten weten dat we het juiste wachtwoord kennen? Daarvoor gebruiken we een zogeheten nonce. Dat is een uniek en willekeurig stukje tekst voor eenmalig gebruik. Die wordt ook maar één keer over het netwerk verzonden. Zo'n nonce bevat meestal de datum+tijd waarop hij is gegenereerd, waardoor het al uniek wordt, plus verder een volslagen willekeurig stukje tekst van een zekere lengte. Het liefst gemaakt met een echte Random Number Generator, gebaseerd op echte ruis, dus niet reproduceerbaar en absoluut onvoorspelbaar. Zo'n RNG moet dan niet volledig rekenkundig zijn bepaald, maar ook gegevens "van buitenaf" verwerken, zoals bijvoorbeeld tijdstippen van door gebruikers gedane toetsaanslagen of muisbewegingen. Ook het exacte "pad" dat een muis aflegt is zelfs voor een gebruiker met bijzonder vaste hand niet precies tot op de pixel en milliseconde reproduceerbaar en kan dus als basis dienen voor en goede RNG. Een nonce zou er bijvoorbeeld zo uit kunnen zien:
Die nonce wordt gegenereerd door de server en dan naar de client verzonden. Op de client moet jij dan je gebruikersnaam en wachtwoord intikken. Vervolgens doet jouw client-software het volgende:
En de server doet het volgende:
De kracht van deze methode zit hem in het slechts één keer gebruiken (en met name verzenden) van die nonce, en in het combineren daarvan met de geheime informatie (de vingerafdruk van naam+wachtwoord). En daarvan dan weer de vingerafdruk. Die is onvoorspelbaar en onomkeerbaar. En omdat de nonce slechts één keer wordt gebruikt gaat die vingerafdruk ook maar 1 keer over het netwerk. En dan is het - gewoon door het gigantisch aantal mogelijkheden - niet te ontcijferen. Omdat er veeeel te weinig en veeeel te trage computers in het veeeel te jonge heelal zijn... Daarom moet het maken van een goede vingerafdruk dus éénrichtingsverkeer zijn, zoals al eerder gezegd. Dan kun je er de oorspronkelijke informatie mee geheim houden terwijl je wel kunt bewijzen dat je die informatie kent. Bovendien heeft een goede nonce een beperkte geldigheid, de server houdt bij op welk tijdstip de nonce is verzonden en accepteert alleen maar antwoorden die binnen een bepaalde tijd terugkomen. En alleen maar van dezelfde computer als waar de nonce heen is gestuurd. Dit principe, waarbij je dus middels de nonce door de server wordt "uitgedaagd" om te bewijzen dat je het juiste wachtwoord kent, wordt meestal aangeduid met de term challenge/response.
Authenticatie & autorisatie
Authenticatie
Autorisatie De procedure is dus altijd een tweetrapsraket: eerst vaststellen wie je bent en daarna pas bepalen wat je mag. Authenticatie doe je op basis van gebruikersnaam plus wachtwoord, autorisatie doe je uitsluitend op basis van de gebruikersnaam, nadat authenticatie heeft plaatsgevonden. De hierboven uitgelegde client/server wachtwoordcontrole is authenticatie. Geen autorisatie.
(A)symmetrische encryptie Er bestaat ook asymmetrische encryptie, dan heb je daarvoor twee verschillende sleutels nodig. Dus een soort kluisje met een heel speciaal slot en twee verschillende sleutels. Als het open is kun je het met elk van die sleutels op slot doen, maar als het op slot is kan het alleen maar worden geopend met de andere sleutel. Ik heb één van die sleutels, jij de andere. Als ik dan het gesloten kluisje ontvang en het met mijn sleutel kan open maken weet ik absoluut zeker dat jij het met jouw sleutel op slot hebt gedaan. En omgekeerd. Maar de asymmetrie gaat nog een beetje verder. Stel dat ik zelf dat slot met die sleutels heb laten maken. De ene sleutel houd ik zelf en ik zorg dat niemand er aan kan komen. Mijn privésleutel. Om hem te herkennen kleur ik hem rood. Van de andere sleutel maak ik een heleboel kopieën en die kleur ik groen. Ik geef iedereen die met mij wil communiceren zo'n kopie. De publieke sleutel dus. Nu is niet alleen de encryptie asymmetrisch, maar ook de communicatie die we op die basis gaan verrichten. De communicatie van mij naar jou houdt alleen maar in dat ik mijzelf kan identificeren. Ik ben immers de enige met de rode sleutel, dus als jij van mij zo'n kluisje krijgt en je kunt het met jouw groene sleutel openen, dan weet je zeker dat het van mij komt. Zeker als er dan een briefje in zit met mijn handtekening. Je communiceert dus echt met mij en niet met iemand anders die net doet alsof hij mij is. De communicatie van jou naar mij is nu uitermate geschikt om vertrouwelijke informatie naar mij te versturen. Je hebt bijvoorbeeld iets bij mij gekocht wat je moet betalen en daarvoor schrijf je je creditcardnummer op een briefje met ook je handtekening. Dat doe je in het kluisje en je doet het op slot met de groene sleutel. Vanaf dat moment kan niemand het nog openmaken, behalve ik. Zelfs jijzelf kunt het niet meer openen! Al die andere mensen met een groene sleutel hebben daar niets aan, want het kluisje is door jou met de groene sleutel op slot gedaan, dus het kan alleen nog maar open met mijn rode privésleutel. Je weet dan zeker dat je je creditcardnummer alleen maar naar mij stuurt en niet naar een of andere oplichter. Hoe krijg je dat nu voor elkaar in een digitale vorm? Wel, daar is echt hogere wiskunde voor nodig. Getallentheorie in ultima forma. Ik zal daar niet tot in alle details op ingaan, en het wiskundige bewijs waarom het werkt laat ik ook achterwege. Alleen het principe ga ik uitleggen.
Grote priemgetallen
De eerste 100 priemgetallen zijn:
Nu is het zo, dat het vinden van priemgetallen op zich gemakkelijk is, maar naarmate ze groter worden wordt het wel steeds bewerkelijker. Er is namelijk geen methode bekend om priemgetallen via een of andere formule te produceren. Als je een serie priemgetallen hebt, kun je niet van daaruit snel uitrekenen wat het volgende priemgetal is. En zoals je in bovenstaand lijstje al kunt zien komen er bij priemgetallen af en toe "tweelingen" voor, priemgetallen die twee opeenvolgende oneven getallen zijn. Met een verschil van twee dus. En zulke tweelingen blijven voorkomen in de lijst van priemgetallen, ook bij de heel erg grote. Dit betekent kortgezegd dat de enige manier om de volledige serie van grote priemgetallen te vinden is om letterlijk alle oneven getallen te testen op deelbaarheid! Priemgetallen die we gemakkelijk als opeenvolgende serie kunnen vinden noemen we kleine priemgetallen. Maar vergis je niet, klein is hier een betrekkelijk begrip. We praten wel degelijk over heel grote getallen. Maar vanaf een zekere waarde is de lijst niet meer compleet. De "priemgetallenjagers" blijven echter wel op zoek en de lijst van bekende kleine priemgetallen wordt dus steeds langer. Maar feit is dat er op een gegeven moment dus gaten in de lijst vallen. Testen of één groot getal wel of niet priem is kan overigens best in een redelijk korte tijd. Daar hebben wiskundigen slimme methodes voor kunnen bedenken. Overigens wel voer voor een computer, met de hand hoef je daar echt niet aan te beginnen. Vergelijk het met de (bekende?) deelbaarheidsregeltjes zoals bijvoorbeeld: een getal is deelbaar door 5 als het eindigt op 0 of 5 en het is deelbaar door 9 als de som der cijfers deelbaar is door 9. Je hoeft de eigenlijke deling niet uit te proberen om te kijken of het lukt. Op zo'n soort manier werkt ook de "priemcontrole", maar dan natuurlijk toch wel iets ingewikkelder. Voor heel grote getallen moet je dan denken aan een computer-rekentijd van pakweg een tiende seconde of zo. Per test. Als je dus bijvoorbeeld alle priemgetallen van 50 cijfers zou willen vinden, moet je alle oneven getallen van 50 cijfers testen. Dat zijn dus alle oneven getallen
Het aantal tests dat je moet doen is dan ook een getal van 50 cijfers. Laten we een supercomputer bedenken die 1 miljoen zulke tests per seconde kan doen. En dat we 1 miljard van zulke computers aan het werk kunnen zetten. Dus 1 miljard maal 1 miljoen = 1000000000000000 tests per seconde, een getal van 16 cijfers. Dan is, om de lijst compleet te maken, de totale benodigde rekentijd in seconden dus een getal van 50 - 16 = 34 cijfers. Met de pakweg 30 miljoen seconden die er in een jaar zitten dus een aantal jaren van 26 cijfers. Hadden we hierboven al niet een beetje gerekend met de leeftijd van het heelal? Het is dus doodgewoon praktisch onmogelijk om de lijst van grote priemgetallen "helemaal vol" te krijgen! De lijst van bekende priemgetallen van zeg 150 cijfers is dus vrijwel helemaal leeg! (Kijk ook eens hier als je daar nog wat meer inzicht in wilt krijgen.) Maar als we een willekeurig getal van 150 cijfers willen testen op deelbaarheid zijn we toch in pakweg een tiende seconde klaar. En er zijn veel priemgetallen, dus na niet al te veel (willekeurige) pogingen vind je er gewoon een. Het is dus niet zo moeilijk om twee verschillende priemgetallen te vinden van elk 150 cijfers. En als je die dan met elkaar vermenigvuldigt krijg je een getal van 300 cijfers. Stel nu dat je zo'n getal van 300 cijfers krijgt, wetend dat het een product is van twee grote priemgetallen, maar je weet niet welke priemgetallen dat zijn. Kun je die dan gemakkelijk terugvinden uit dat getal van 300 cijfers? Forget it! (Mits die priemgetallen verschillend waren, want worteltrekken is ook bij 300 cijfers een fluitje van een cent.) Dat getal van 300 cijfers is immers alleen maar deelbaar door die twee priemgetallen en verder helemaal nergens door. Als je die twee priemgetallen niet weet vind je ze ook niet. Want dan zou je dat getal van 300 cijfers moeten proberen te delen door alle priemgetallen tot dat je de kleinste van die twee tegenkomt. Zodra het delen zou lukken heb je natuurlijk het andere priemgetal ook, maar omdat het vinden van het eerste priemgetal dus onmogelijk is kom je er niet uit. Je zoekt niet een speld in een hooiberg, nee, zelfs niet 1 atoom in het hele heelal! Astronomen schatten het totaal aantal atomen in het hele heelal (voor zover we het kennen) op een getal van 81 cijfers, dus dat kan niet tippen aan onze priemgetallen van 150 cijfers! Nog even dit: elk natuurlijk getal is ofwel een priemgetal dan wel te schrijven als een product van priemgetallen, waarbij hetzelfde priemgetal best meer dan 1 keer mag voorkomen. Bijvoorbeeld:
Het proces om van een getal die samenstellende priemgetallen te vinden heet "ontbinden in priemfactoren". En nog een begrip dat nodig is: "copriem". Simpel gezegd: één getal is priem als er geen enkel getal is waar je het door kan delen, twee getallen zijn copriem als er geen enkel getal is waar je ze allebei door kunt delen. Of, in een betere wiskundige formulering: twee getallen zijn copriem als de grootste gemene deler 1 is. In het lijstje hierboven zie je dat bijvoorbeeld 33 en 35 copriem zijn. Geen gemeenschappelijke priemfactoren.
RSA-methode Overigens, voor alle duidelijkheid: er bestaat géén wiskundig bewijs dat ontbinden in priemfactoren de enige manier zou zijn om de RSA-methode te kraken, en er bestaat ook géén wiskundig bewijs dat ontbinden in priemfactoren niet heel snel zou kunnen. Alleen weet men geen enkele snelle methode voor het ontbinden in priemfactoren en we weten geen andere methode om RSA te kraken. En de heren wiskundigen zijn er wel degelijk heel sterk van overtuigd dat die twee dingen niet kunnen. Maar er is dus geen bewijs voor. Zodra iemand wel een snelle methode zou vinden is het hele principe volslagen waardeloos, en dan heeft de hele wereld ineens een heel groot probleem als het bijvoorbeeld gaat om electronisch betalingsverkeer! Verder definiëren we nog de z.g. mod operator ('mod' staat voor 'modulo'). Met die operator bepaal je de rest bij deling, dus b.v. 12 mod 7 = 5. Je kunt je afvragen: wat heeft dat voor nut, alleen maar de rest bij deling en het quotient weggooien? Nou denk eens aan de klok. Die is modulo 12. We zijn vaak alleen geïnteresseerd in het tijdstip op de dag, niet in het aantal dagen dat sinds een of andere datum is verstreken. En soms zijn we wel geïnteresseerd in de dag, en dat doen we dus modulo 7. En de maanden doen we modulo 12. Dus zo raar is die 'mod' operator niet...
De RSA methode gaat nu als volgt.
Nu we zo'n sleutelpaar hebben gaat de encryptie en decryptie als volgt, en dat is het wiskundige "foefje" waardoor de encryptie asymmetrisch is. Je gaat met de publieke sleutel [E,N] een boodschap versleutelen en naar een server zenden die over de privésleutel [D,N] beschikt:
Je zou nu wellicht kunnen denken dat je uit deze laatse symmetrie gemakkelijk D kunt bepalen als je M en C kent, terwijl N uiteraard ook bekend is. Nou, niet dus. Ook hier is het aantal uit te proberen mogelijkheden namelijk weer te groot voor het heelal. En zoals je aan die symmetrie ook kunt zien maakt het dus eigenlijk niet uit wat je als de boodschap beschouwt, M of C. Maar er is dus wel een ander soort asymmetrie aanwezig: wat de server versleutelt met [D,N] kan worden ontsleuteld door iedereen die de publieke sleutel [E,N] heeft. Dus niet geschikt voor geheimhouding. En wat met [E,N] is versleuteld kan uitsluitend door de server met [D,N] weer worden ontsleuteld. Dus wel geschikt voor geheimhouding. Op Paj's Home vind je een goede wiskundige verhandeling over de RSA-methode, en op de site van Leemon Baird kun je leuk met RSA spelen (maar dan wel met kleinere priemgetallen, het is een demopagina).
Digitale handtekening
Symmetrisch en asymmetrisch gecombineerd Hoe gaan we dan in de praktijk te werk? Nou gewoon zo: Jij maakt contact met mijn server, ik stuur jou een op zichzelf onbelangrijk bericht met mijn digitale handtekening. Dan kun jij verifiëren dat je daadwerkelijk met mij verbinding hebt en met niemand anders. Vervolgens genereer jij op jouw eigen pc met een PRNG een volslagen willekeurig stukje tekst, dat op dat moment dus niemand kent behalve jij. Dat stukje tekst versleutel je met de publieke sleutel en je stuurt dat naar mij. Niemand kan het ontsleutelen, behalve ikke! Dan zijn wij met z'n tweetjes de enigen die dat door jou gegenereerde stukje tekst kennen. En verder helemaal niemand. Maar dan kunnen we dat stukje tekst toch gewoon gebruiken als sleutel voor symmetrische encryptie? Dat gaat wel snel!
Certificaten Welnu, stel dat een andere instantie voor jou wel betrouwbaar is, bijvoorbeeld een notaris die in een officieel document verklaart dat ik mij bij hem persoonlijk heb gelegitimeerd en dat mijn digitale handtekening legitiem is, dan kun je mij wel vertrouwen, nietwaar? En een dergelijke procedure wordt dus gevolgd. Instanties die betrouwbaar willen en moeten zijn, zullen niet zomaar zelf een sleutelpaar genereren. Zij gaan daarvoor naar een zogeheten Certifying Authority, dat is een instelling vergelijkbaar met een notariskantoor. Verisign en Thawte zijn bijvoorbeeld bekende C.A.'s, de kans is groot dat je die namen al eens op je beeldscherm hebt gehad in een pop-up venster om te bevestigen of je een of andere website wilt vertrouwen. Die C.A. genereert dan voor jou een sleutelpaar, nadat jij je persoonlijk bij hen hebt gelegitimeerd. Met een officieel document. Paspoort of rijbewijs of zo. En als je daar namens een bedrijf komt moet je ook een inschrijvingsbewijs van de Kamer van Koophandel overleggen. Vervolgens krijg jij dat sleutelpaar plus een digitaal certificaat, waarin de C.A. verklaart dat ze jouw identiteit persoonlijk hebben vastgesteld via deugdelijke legitimatie en dat jij de enige houder bent van dat sleutelpaar. Jij hebt dan natuurlijk de verplichting om jouw privésleutel goed geheim te houden! En, net zoals de notaris zijn documenten ondertekent met zijn eigen handtekening, is dat certificaat voorzien van de digitale handtekening van de C.A. zelf. In het vorige hoofdstukje had ik geschreven: "Ik stuur jou een op zichzelf onbelangrijk bericht met mijn digitale handtekening". Nou, zo onbelangrijk is dat bericht helemaal niet, ik stuur namelijk een kopie van mijn certificaat! Daarmee krijg je mijn publieke sleutel toegestuurd en het bevat de identificatie plus digitale handtekening van de Certifying Authority. Vergelijk het met een door mij gesigneerde kopie van de notarisverklaring. Als je het certificaat niet vertrouwt kun je zelf naar de website van de genoemde C.A. gaan en daar nog een kopie van dat certificaat opvragen. Die moet dan identiek zijn aan wat ik heb meegestuurd en dan weet je dat het certificaat echt van die C.A. afkomt en dat die sleutel dus echt door hen aan mij is uitgereikt. En als jij het dan vertrouwt, kun je met je creditcardnummer iets bij mij kopen. Veilig. En als je de C.A. niet vertrouwt? Wel, dan kun je ter verificatie een certificaat ophalen van een overkoepelende organisatie, die met weer een eigen digitale handtekening verklaart dat die C.A. wel degelijk betrouwbaar is. Vergelijk dat met een verklaring van de bond van notarissen waarin staat dat de betreffende notaris betrouwbaar is. Met handtekening van de voorzitter van de bond van notarissen. Dan wordt dus door een betrouwbare notaris verklaard dat mijn website betrouwbaar is. Nou, dan kun je mij echt wel vertrouwen hoor! Of toch niet? Wie zegt dat de bond van notarissen betrouwbaar is? Afijn, dit spelletje kunnen we eindeloos herhalen, met certificaat op certificaat op certificaat etc. Ergens kom je op het punt dat jij zelf de knoop moet doorhakken en kiezen: "ik vertrouw de ander wel of niet." En als dat "niet" is moet je van die site wegsurfen en er niets kopen met je creditcard. Alleen jijzelf maakt uiteindelijk uit hoe betrouwbaar jij een andere partij vindt. Verder: ik kan wel zeggen en bewijzen dat ik Henk Reints ben en jij kunt er volledig van overtuigd zijn dat ik inderdaad Henk Reints ben, maar dat betekent nog steeds niet dat ik betrouwbaar ben... Met handtekening en certificatie bewijs je uiteindelijk alleen maar dat je bent wie je zegt te zijn, niet meer dan dat.
Vertrouwen Overigens moet je ook de software die je gebruikt kunnen vertrouwen. Ik kan jou best een programmaatje sturen en erbij zeggen dat het een deugdelijke versleuteling doet en dat je daarmee dus beveiligde websites kunt bezoeken, maar wat als ik er stiekem iets heb ingebouwd dat jouw creditcardgegevens toch onbeschermd in mijn eigen database opslaat? Zodat ik daarna op jouw kosten kan gaan feestbeesten? Zou Internet Explorer wel betrouwbaar zijn? En Netscape? Of Opera, of ...? Wel als ze digitaal zijn ondertekend met een certificaat van een betrouwbare C.A. En op jouw pc staat ergens een lijst van betrouwbare Certifying Authorities, d.w.z. dat jij de certificaten van die instanties vertrouwt, zodat je niet bij elk bezoek aan een site met zo'n certificaat telkens opnieuw op "OK" hoeft te klikken om te vertellen dat jij die site vertrouwt. Soms bezoek je een site met een certificaat van een C.A. die niet in die lijst staat, en dan krijg je wel een venstertje om te vertellen of je wel of niet verder durft te gaan. Als je het niet vertrouwt moet je dan niet op "OK" klikken! Wellicht kun je je niet herinneren dat je ooit die lijst van betrouwbare C.A.'s hebt ingevoerd. Dat heb je ook niet. Je weet die lijst waarschijnlijk niet eens te vinden! (klik hier voor een voorbeeld). Microsoft heeft die lijst bij de installatie van Windows alvast voor je klaargezet. Vertrouw jij Microsoft? Cirkels zijn rond... Het hele verhaal begint en eindigt met vertrouwen. Als je iemand niet vertrouwt moet je hem nooit een geheim vertellen. Zelfs niet zeggen dat je een geheim hebt. Alleen een geheim geheim is geheim.
Steganografie Behalve dat je informatie kunt versleutelen, waarmee je de boodschap voor outsiders onleesbaar maakt, is het ook nog mogelijk een boodschap zodanig te verbergen dat het zo goed als onherkenbaar wordt dat je überhaupt een geheime boodschap verstuurt. Want zeg nou zelf, als een afluisteraar ziet dat ik jou een serie tekens stuur waar op geen enkele manier iets zinnigs van te maken is, dan kan hij gemakkelijk veronderstellen dat het een versleutelde boodschap is. En de C.I.A. zal het toch wel heel erg verdacht vinden als ik kennelijk versleutelde boodschappen aan het versturen ben. Maar als ik jou nou eens een leuke zelfgemaakte vakantiefoto stuur met een begeleidende tekst die ook over mijn vakantie gaat, dan heeft de afluisteraar waarschijnlijk niets in de gaten. En in die foto kan dan een geheime boodschap verborgen zitten. Want de precieze waarden van de kleuren en helderheden van elk beeldpunt in de foto komen niet zo heel erg nauw voor het menselijk oog, toch? Heel kleine nuanceverschillen zien we doodgewoon niet. Dat betekent dat we best een paar bitjes van een foto kunnen "stelen" om er een geheime boodschap in te zetten. Zo iets heet steganografie. Het verbergen van informatie. Het beste is het natuurlijk als je de informatie zowel versleutelt als verstopt. Dan wordt de kans dat men je boodschap vindt wel heel erg klein. Overigens zijn er natuurlijk wel weer heel erg geavanceerde statistische analysemethodes om te proberen te achterhalen of een foto geheime informatie bevat. Maar je kunt het de tegenstander wel heel erg moeilijk maken, zo niet onmogelijk, om met zekerheid vast te stellen dat je een boodschap hebt en wat dan die boodschap is. Van mijn javascriptpagina kun je enkele kant en klare scripts downloaden om bestanden te versleutelen of steganografisch in foto's te verstoppen. Overigens is die pagina in het Engels. En let wel, het zijn en blijven slechts voorbeeldscripts, de gebruikte algoritmes zijn niet goed genoeg voor militaire toepassingen. |
Links naar andere websites
|
Copyright & disclaimer
|
N.B.
Ik heb een reactie gekregen op deze pagina met de opmerking dat er "geen woord Chinees" in stond. Dat wil ik bij deze graag corrigeren: Babi Pangang! |