de uitleg

advertisement
RSA
Inleiding
RSA is een encryptiemethode die in 1977 beschreven werd door Ron Rivest, Adi Shamir en
Leonard Adleman (vandaar de naam RSA).
Als je de RSA-methode veilig wilt gebruiken moet je heel grote priemgetallen1 gebruiken bij de
codering. In de uitleg hieronder gaan we uit van kleine priemgetallen, omdat dat gemakkelijker
leest.
Als je rechtsboven een woord of zin een getal ziet staan wil dat niet zeggen dat je dat woord of die
zin tot die macht moet verheffen, maar er staat dan wel een voetnoot onderaan de pagina.
In de coderingstheorie worden de ontvanger en verzender van een bericht vaak Alice en Bob
genoemd (afgekort als A en B). Bij deze opdracht houden we ons aan die traditie.
De methode
voorbereiding
Schrik niet! Er komt nogal wat wiskunde kijken bij het versleutelen met RSA.
Alice gaat als volgt te werk:







Kies twee verschillende priemgetallen p en q
Bereken n= pq
n = p− 1 q− 1
Bereken de zogenaamde totiënt:
n ligt en dat geen deler met
Kies een getal e dat tussen 1 en
2 e
heeft . vormt samen met n de publieke sleutel.
Bereken d zodat de≡ 1 mod n 3 4.
d vormt samen met n de geheime sleutel.
Vernietig p en q.
n
gemeenschappelijk
1 Een priemgetal is een geheel positief getal groter dan 1, dat alleen door zichzelf en 1 deelbaar is. Vier is dus geen
priemgetal omdat het ook deelbaar is door twee.
2 3 en 9 hebben 3 als gemeenschappelijke deler. 8 en 12 hebben 2 als gemeenschappelijke deler. Er is altijd een
kleinste gemeenschappelijke deler (de KGV). Als die 1 is hebben de twee getallen geen echte deler
gemeenschappelijk.
3 Als a≡ b mod n is b de rest van de deler a gedeeld door n. Dus 7≡ 1 mod 3 . Als k het aantal keer is dat n op a
te delen is geldt dus 7= 1 3k .
In NSBasic bereken je dit met a=mod(b,n) en in Pascal/Delphi met a:=b mod n
n bij 1 op te tellen en dan te kijken of je e er precies op kunt delen. De uitkomst is
4 Je kunt dat dus doen door
dan d.
Coderen/versleutelen van de boodschap
Alice stuurt n en e naar Bob. d houdt ze geheim. Als Bob nu een bericht B naar Alice wil sturen
moet hij het volgende doen.
Allereerst moet hij het bericht in een getal m omzetten5. M moet daarbij kleiner dan n zijn. Als m
groter dan n is, moet hij het bericht in kleiner stukken verdelen. De gecodeerde tekst (het in
inmiddels een
getal) berekend hij dan met:
c= me mod n
Alle getallen c stuurt Bob nu in de juiste volgorde naar Alice. Als we bijvoorbeeld de getallen 83, 6,
873 willen sturen moeten we er een scheidingsteken tussen zetten (in deze tekst is dat een komma,
maar het mag ook iets anders zijn).
We kunnen er ook voor kiezen om de getallen even lang te maken, door er nullen voor te plakken.
We kunnen ze dan wel achterelkaar plakken: 083006873.
In dit voorbeeld hebben we nullen voor het getal geplakt tot de lengte drie was. Omdat de nul in
deze gecodeerde tekst wel heel erg vaak voorkomt zal een fraudeur al snel op het idee komen dat
we de getallen met nullen aangevuld hebben. De conclusie dat de getallen maximaal 3 cijfers lang
zijn, is dan niet meer zo moeilijk6.
Decoderen/ontsleutelen van de boodschap
Alice ontvangt een aantal getallen c. Elke getal rekent ze dan weer om naar m op de volgende
manier:
m= c d mod n
Bewijzen dat dit klopt, is (mooie) wiskunde.
Voorbeeld
We gaan de methode nu met concrete getallen illustreren.




Kies twee verschillende priemgetallen p en q : p=53 en q=61
Bereken n= pq : n=53*61=3233
n = p− 1 q− 1 :(61-1)*(53-1)=3120
Bereken de zogenaamde totiënt:
n ligt en dat geen deler met
n gemeenschappelijk
Kies een getal e dat tussen 1 en
heeft7. We kiezen voor e= 17 .8
5 De methode die Bob gebruikt om M in m om te zetten moet natuurlijk omkeerbaar zijn, zodat Alice m in M kan
omzetten. Alice moet natuurlijk weten hoe ze dat moet doen. Een eenvoudige (en niet zo veilige methode) is het
gebruiken van de ASCII-waarde van een teken (waarom is dat niet veilig?). Het wordt al wat moeilijker als je meer
dan 1 teken tegelijk in het getal verwerkt. Je zou de tekenreeks AB kunnen omzetten naar een getal met
g=256*ASC('A')+ASC('B').
6 Je kunt de getallen ook met behulp van een wiskundige functie omrekenen naar een ander getal dat maximaal drie
127
cijfers langs is, bijvoorbeeld: g = m mod 1000
7 3 en 9 hebben 3 als gemeenschappelijke deler. 8 en 12 hebben 2 als gemeenschappelijke deler. Er is altijd een
kleinste gemeenschappelijke deler (de KGD). Als die 1 is hebben de twee getallen geen echte deler
gemeenschappelijk.
8 Als je voor e een priemgetal kiest, heb je zeker een getal dat geen deler de totiënt gemeenschappelijk heeft.


Bereken d zodat de≡ 1 mod n
k=15, dan vinden we d=2753.
Vernietig p en q.11
9 10
. We proberen achtereenvolgens k=1, k=2, k=3,... Bij
Als Bob nu het teken { willen coderen, kan dat als volgt:
17
De ASCII-waarde van { is 123. Dus m= 123 . c= 123 mod 3233= 855 .
2753
Alice vindt de oorspronkelijke boodschap weer met m= 855 mod 3233= 123 .
Kies natuurlijk willekeurig.
9 Als a≡ b mod n is b de rest van de deler a/n. Dus 7≡ 1 mod 3 . Als k het aantal keer is dat n op a te delen is
geldt dus 7= 1 3k .
n bij 1 op te tellen en dan te kijken of je e er precies op kunt delen. De uitkomst is
10 Je kunt dat dus doen door
dan d.
11 Oeps...
Details
kies k=15
Er zijn een aantal plekken waar je tegen problemen aanloopt. Zo stellen we in de voorlaatste stap
dat je d wel kon vinden door k=15 te kiezen. Maar hoe weet je dat?
Dat weet je inderdaad niet 1-2-3. Wiskundige gezien moet je de inverse van d modulo n uitrekenen.
n −1
mod n , dus in het geval van
Dat kan met het algoritme van Euclides. Daaruit volgt dat d = e
3119
het voorbeeld d = 17 mod 3120 .
Als je dat algoritme te ingewikkeld vindt, kun je ook achtereenvolgens k=1, k=2, …, etc. proberen.
Voorbeeld:
k=1
d⋅ 17≡ 1 k⋅ 3120
d⋅ 17≡ 1 1⋅ 3120
d⋅ 17≡ 3121
d ≡ 3121/17≈ 183,6
d is geen geheel getal, we moeten dus de volgende waarde van k proberen.
2753
Bereken m= 855 mod 3233= 123
2753
Hoe reken je dit uit? Je doet dat niet door 855 te berekenen. De rekenmachine van Windows
8071
zegt dat dit ongeveer 5,05× 10 . Dat is dus een getal van 8072 cijfers! Aangezien in 16 bits
hooguit het getal 65535 past, zal dit getal dus zeker niet passen. Rekenen met kommagetallen is
geen optie omdat we de exacte rest moeten berekenen. (Leuke vraag: hoeveel bits zou je nodig
hebben om dit getal op te slaan?12)
We berekenen het als volgt:
m= 1
m= 1× 855 mod 3233= 855
m= 855× 855 mod 3233= 367
m= 367× 855 mod 3233= 184
...
...
Op deze manier vermenigvuldigen we 2753 maal met 855. Het tussenresultaat blijft dus steeds
kleiner dan 855x3233=2764215. Dat past in een integer.
8071
12 Bereken log 5,04× 10
/log 2= 26813 (bits).
In pseudocode zou dat er zo uit kunnen zien:
macht=2753
uitkomst=1
e=855
n=3233
for teller=1 to macht
uitkomst=mod(uitkomst*e,n)
next
Hoe bepaal je de ASCII-waarde van een letter?
In Delphi gaat dat als volgt:
Ga er van uit dat s een string is die een tekst bevat.
Het i-de teken lees je dan uit met s[i].
Het aantal tekens in s bepaal je met length(s).
De ASCII-waarde van dat teken bepaal je met ord().
Hieronder staat pseudocode
// declaraties van de variabelen
var s,t:string;
i:integer;
// bepalen van alle ASCII-waarden van de tekens in s
for i:=1 to length(s) do begin
t:=s[i];
showmessage(IntToStr(Ord(t));
end;
Hoe bepaal je het teken dat bij een ASCII-waarde hoort?
Met de functie chr() krijg je het teken dat bij een ASCII-waarde hoort.
Stel dat je een string wilt maken van de 3 ASCII-waarden 65, 66 en 67. Dan kan dat als volgt:
s := chr(65)+chr(66)+chr(67);
Hoeveel tekens tegelijk coderen?
Coderen per teken (dus voor 1 teken tegelijk) is onzinnig omdat je nog steeds kunt tellen welke
letters het meeste voorkomen. Dezelfde letter worden immers op dezelfde manier gecodeerd: als
een 65 (ASCII-code van 'A') gecodeerd wordt tot 213, dan worden alle A's als 213 gecodeerd.
Je moet daarom voor een groepje letters coderen.
Hoe vat je drie ASCII-waarden in één getal samen?
Het decimale getal 123 bestaat uit 3 tekens: 1, 2 en 3.
Elke positie kan maximaal de waarde negen hebben.
2
De waarde van de drie tekens is 1× 10 2× 10 3× 1
Als je drie tekens codeert gaat dat bijna hetzelfde. Neem bijvoorbeeld de string 'ABC'. Die bestaat
uit de tekens 'A', 'B', 'C'. Elke teken heeft een ASCII-waarde: 'A' → 65, 'B' → 66, 'C' → 67.
De waarde van een ASCII-waarde is minimaal 0 en maximaal 255.
We kunnen de string 'ABC' dus de volgende waarde geven:
65× 2562 66× 256 67× 1= 4276803
Bij decimale getallen is het niet moeilijk om uit een getal de eenheden, tientallen, en honderdtallen
te halen. Met moet daarvoor de rest bij deling kunnen bepalen.
Voorbeeld
7 : 3 = 2 rest 1
Je berekent in Delphi de rest met de opdracht mod:
rest := 7 mod 3; //in rest staat nu de waarde 1
We nemen als voorbeeld het getal 987.
Hoeveel eenheden zitten er in 987?
987 : 10 = 98 rest 7 → dus 7 eenheden
bereken nu (987 – 7) : 10 = 98
De 8 van 98 staat in het getal 98 voor de eenheden, maar in het oorspronkelijke getal de
tientallen.
Hoeveel tientallen zitten er in 987?
98 : 10 = 9 rest 8 → dus 8 tientallen
Bereken nu (98 – 8) : 10 = 9
De 9 zijn eenheden, maar in het oorspronkelijke getal de honderdtallen.
Hoeveel honderdtallen zitten er in 987?
9 : 10 = 0 rest 9 → dus 9 honderdtallen
Op dezelfde manier kunnen we het getal 4276803 terugrekenen naar de drie losse ASCII-waarden.
4276803 : 256 = 16706 rest 67
16706 : 256 = 65 rest 66
65 : 256 = 0 rest 65
Je ziet dus dat de drie oorspronkelijke ASCII-waarde als rest uit de berekeningen komen.
Grote getallen
Als je met heel grote getallen wilt kunnen rekenen kun je deze bibliotheek met speciale
rekenfuncties gebruiken.
Opdracht 1
Maak in je Google Account een spreadsheet aan waarin je bijhoudt wanneer je aan het programma
gewerkt hebt. Deel dat document met [email protected] zodat het document te lezen is (en dus
niet te bewerken).
Vermeld elke keer het volgende:
datum,
starttijd,
eindtijd,
totale tijd
wat is er gedaan
Opdracht 2
Je docent geeft je 1 van de volgende opdrachten:



Schrijf een programma dat d, e, n berekent.
Schrijf een programma dat een bericht codeert met e,n. Het versleutelde bericht moet in een emailbericht te plakken zijn.
Schrijf een programma dat een bericht decodeert met d,n. Het gedecodeerde bericht moet te
kopiëren zijn naar een tekstverwerker.
De programma's moeten zo gemaakt zijn dat ze met elkaar samen kunnen werken.
Daarbij moet je een aantal problemen oplossen:
 hoe zet je een tekst om naar getallen
 hoe zet je dat getal om naar een getal met een vaste lengte, etc. Al deze omzettingen moeten
natuurlijk ook in omgekeerde richting werken.
Extra 1: Als je in het bestand een username/usercode opneemt kan het programma zelf de juiste
sleutel er bij zoeken.
Extra 2: Bij de laatste twee programma's verdien je pluspunten als je drag and drop implementeert:
als je een bestand op het venster sleept wordt het meteen gedecodeerd.
Je kunt kiezen uit de programeer talen Python, Java, NS-Basic, Delphi.
Opdracht 3
Vermeldt in je logboek hoeveel tijd je aan de opdracht gewerkt heb, en hoeveel tijd jouw
groepsgenoten naar schatting aan de opdracht gewerkt hebben.
Nabespreking
- Relatieve en absolute tijdsbesteding
- Ontwerpmethode: Ontwerpen, implementeren en testen
Download