Kap.1) DAS RSA-VERFAHREN
in Java für beliebig große BigInteger-Zahlen
Index
1.1 Das RSA-Verfahren
1.2 RSA-Verfahren in Java, Zahldarstellung BigInteger
1.3 RSA-Verfahren in Java, Durchrechnung von Beipielen
Das RSA-Verfahren mit öffentlichem Schlüssel zur Verschlüsselung und geheimem Schlüssel zur Entschlüsselung von Nachrichten
wurde 1977 von Ron Rivest, Adi Shamir und Len Adleman entwickelt
und ist heute in der Internet-Nachrichtenübertragung ein häufig
verwendetes und in der Kryptographie-Literatur das am ausführlichsten behandelte Verfahren.
Das Prinzip des RSA-Verfahrens besteht darin, daß man leicht,
in wenig Rechenzeit, aus zwei geheimzuhaltenden großen Primzahlen
p,q das öffentlich bekanntzugebende Produkt n=p*q berechnen kann,
aber nur sehr schwer, in ggf. zu langer Rechenzeit, die öffentlich
bekannte Zahl n wieder in ihre beiden geheimen Primfaktoren p,q
zerlegen kann. Sein Reiz besteht darin, daß der erforderliche Aufwand zur "Faktorisierung" (uns) bisher nicht bekannt ist. Man
nimmt an, daß eine Zahl n von mindestens 1024 Binärstellen mit
heutiger Rechner-Technologie nicht "faktorisiert" werden kann.
Das RSA-Verfahren verschlüsselt und entschlüsselt nur Zahlen in
Zahlen, d.h. als Vorlauf - und umgekehrt als Nachlauf - muß der
Klartext P (Plaintext) mit einem öffentlich bekannten Code-Alphabet in eine Zahlenfolge E (numerical Encoding) übersetzt werden.
Für einführende Beispiele wählt man z.B. den kurzen Code
" abcdefghijklmnopqrstuvwxyz"
mit den Zahl-Indizes 0..26 und z.B. das öffentlich bekannte Füllzeichen (fill) ' ', z.B. auf Index 0. Außerdem sollten entsprechend der modularen Arbeitsweise des RSA-Verfahrens jeweils so
viele Zahlen mit jeweils führenden Nullen zu einem Block aneinandergereiht werden, daß der Block gerade noch kleiner ist als der
Modul n. Alle Blöcke müssen gleich lang sein, d.h. die Blocklänge
wird bestimmt durch den größten Index des Text-Codes, z.B. 26. Der
letzte Block muß ggf. mangels weiterer Klartext-Zeichen mit Füllzeichen aufgefüllt werden.
Die Blöcke M der Nachricht (Message) werden verschlüsselt in
Blöcke C der chiffrierten Nachricht (Ciphertext) durch
C = M^e mod n (e public encryption key, n public modul)
und umgekehrt werden die Blöcke C der chiffrierten Nachricht wieder entschlüsselt in Blöcke M der Nachricht durch
M = C^d mod n (d secret decryption key, n public modul)
Zur Bestimmung von n,e,d werden zwei voneinander verschiedene
große Primzahlen p,q gewählt. Der öffentliche Schlüssel e wird
relativ prim (teilerfremd) zu ((p-1)(q-1)) gewählt und der geheime
Schlüssel d als ((p-1)(q-1))-modulare Inverse von e, d.h. e*d mod
((p-1)(q-1)) = 1. Eine kurze Übersicht über modulare Arithmetik
findet der Leser in 3.1. Der Beweis dafür, daß die Entschlüsselung der Verschlüsselung von M wieder auf M zurückführt, d.h. (M^e
mod n)^d mod n = M, wird in 3.2.2 geführt. Der effiziente Reduktions-Algorithmus zur Berechnung der modularen Potenzen M^e mod n
und C^d mod n wird in 3.3.3 als Java-Programm dargestellt.
In Lehrbüchern bemüht man sich, dem Leser das RSA-Verfahren
durch Schematisierung verständlich zu machen und an Hand von ausgewählten Beispielen zu erläutern. Wir nutzen den Vorteil der interaktiven Arbeit mit Applets und der sich daraus ergebenden Möglichkeit, selbst Beispiele durchzurechnen. "Das Beste an der Theorie sind immer die selbst durchgerechneten Beispiele" oder wie
Goethe sagt: "Grau, teurer Freund, ist alle Theorie, Und grün des
Lebens goldner Baum" (Faust, Der Tragödie erster Teil, Schüler-Szene).
1.2 RSA-Verfahren in Java, Zahldarstellung BigInteger
Applet-Index
Apl_1: RSA-Verfahren in Java, Zahldarstellung BigInteger
Java scheint mit seiner Klasse Biginteger, die seltsamerweise
in keinem der bekannten Java-Lehrbücher direkt erwähnt wird, von
Anfang an (1996) "maßgeschneidert" zu sein auf das RSA-Verfahren
(1977). Die effizienten modularen Methoden der Klasse BigInteger
werden in 3.3 dargestellt. BigInteger-Zahlen sind nicht beschränkt auf die interne Zahldarstellung der bisherigen 32-Bit
-Rechner oder künftigen 64-Bit-Rechner und erfordern auch keine
Reihungs-Techniken, sondern ermöglichen das direkte Rechnen mit
beliebig großen Zahlen, z.B. mit mehr als 1024 Bit, wie dies heute
aus Gründen der Sicherheit für das RSA-Verfahren verlangt wird.
Die Java-Applets 1 (unten) und 2 (Kap.2) arbeiten mit BigInteger-Zahlen, d.h. sie sind für beliebig große n zugelassen. Zur übersichtlichen Gestaltung der Benutzeroberfläche werden allerdings
die sichtbaren Teile der Ein- und Ausgabetexte beschränkt. In Applet 1 ist zur Einführung ein Modul n mit 12 Bit vorgewählt, der
für die sichere Verschlüsselung in der Praxis viel zu klein ist
und vom Benutzer durch einen größeren Modul ersetzt werden sollte.
In Applet 2 ist bereits ein hinreichend großer Modul n mit 1128
Bit voreingestellt.
Das folgende Applet 1 zeigt die Verschlüselung und Entschlüsselung des Klartextes (Plaintext) "rsa". Voreingestellt ist der öffentliche Code " abcdefghijklmnopqrstuvwxyz" mit dem öffentlichen
Füllzeichen ' ' auf Index 0. Gewählt wurden die geheimen Primzahlen p=61, q=47.
Zunächst überzeugt man sich, daß n=p*q=2867 groß genug gewählt
wurde, damit überhaupt innerhalb des Moduls codiert werden kann,
d.h. n muß größer sein als der größte Index 26 des Codes. Danach
bildet man durch Aneinanderreihung des größten Index des Codes den
größten Block, der gerade noch kleiner als n ist, d.h. 2626<2867.
In diesem Fall ist die Blocklänge 4 (2 Indizes mit je 2 Ziffern).
Kodiert man nun den Klartext "rsa" in die Zahlenfolge E (Encoding)
18,19,01, so stellt sich heraus, daß für die Bildung von Blöcken
der Länge 4 der letzte Block mit dem Füllzeichen (fill) ' ' des
Codes aufgefüllt werden muß, d.h. 1819, 0100,
Apl_1 (Quelltext: www.harry-feldmann.net/Hexen1x1/source/Apl_1.java.html, ... /Apl_1.html.html)
Apl_1: RSA-Verfahren in Java, Zahldarstellung BigInteger
Applet 1 zeigt, daß der Chiffrier-Schlüssel (encryption key)
vorgewählt wurde als e=11 relativ prim (teilerfremd) zu (p-1)(q-1)
=2760. Mit e werden die Blöcke M der Nachricht (Message) in Blöcke
C der chiffrierten Nachricht (Ciphertext) verschlüsselt, d.h. 1819
^11 mod 2867 = 0438, 0100^11 mod 2867 = 0202. Der Dechiffrier-Schlüssel (decryption key) d=251 wird berechnet als
(p-1)(q-1)-modulare Inverse von e=11, d.h. es gilt 11*251 mod
2760 = 1. Mit d werden die Blöcke C der chiffrierten Nachricht
wieder entschlüsselt in Blöcke M der ursprünglichen Nachricht,
d.h. 0438^251 mod 2867 = 1819, 0202^251 mod 2867 = 0100.
Wiederaufteilung der Blöcke M in die Zahlenfolge 18,19,01,00,
und Rückkodierung gemäß Code ergibt den ursprünglichen Klartext
"rsa ", der allerdings wegen Blockbildung inzwischen um ein nachgesetztes Füllzeichen verlängert wurde.
Leser, die selbst mit ihrem (Taschen-) Rechner eine modulare
Inverse bestimmen möchten, z.B. 11*? mod 2760=1, oder selbst eine
modulare Potenz berechnen möchten, z.B. 100^11 mod 2867=?, verweisen wir auf die Beschreibung der entsprechenden effizienten Methoden in 3.3.2 oder 3.3.3.
Die Inverse wird mit dem Euklidischen Reduktions-Algorithmus zur
Bestimmung des größten gemeinsamen Teilers berechnet, der als
"Nebeneffekt" auch die Inverse liefert.
Bei modularen (auch mehr als zweistelligen) Multiplikationen
können Zwischenergebnisse durch zusätzliche Modulbildung auf kleinere Zahlen reduziert werden (mod. Reduktion 3.1.2, 3.1.4), z.B.
11 dezimal entspricht 1 0 1 1 binär
100^11 mod 2867=(((1^2*100^1)^2*100^0)^2*100^1)^2*100^1 mod 2867
=(( 10000 mod 2867)^2*100^1)^2*100^1 mod 2867
=( 1399 ^2*100^1)^2*100^1 mod 2867
=( 1957201 mod 2867 *100^1)^2*100^1 mod 2867
=( 1907 *100^1)^2*100^1 mod 2867
=( 190700 mod 2867 )^2*100^1 mod 2867
= 1478 ^2*100^1 mod 2867
= 2184484 mod 2867 *100^1 mod 2867
= 2697 *100^1 mod 2867
= 269700 mod 2867
= 202
Die Potenz 100^11 wird in eine Kette von Quadrierungen und Einzel-Multiplikationen aufgespalten, die aus der binären Darstellung
des Exponenten 11 ablesbar sind. Die modularen Reduktionen beschränken alle (Zwischen-) Ergebnisse auf Werte kleiner als n^2=
8219689.
1.3 RSA-Verfahren in Java, Durchrechnung von Beipielen
Beispiel-Index
1.3.1 Bauer: "Entzifferte Geheimnisse", ISBN 3-540-67931-6
1.3.2 Salomaa: "Public-Key Cryptography", ISBN 3-540-61356-0
1.3.3 Stalling: "Cryptography and network security", ISBN 0-13-869017-0
1.3.1 Bauer: "Entzifferte Geheimnisse", ISBN 3-540-67931-6
code, public alphabet=" abcdefghijklmnopqrstuvwxyz", index 0..26
p, secret prime :47
q, secret prime :59
e, public encrypt.key:17
P laintext :"errare humanum est"
n, public modul =2773 (4 Dig,12 Bit)
E ncoding =05,18,18,01,18,05,00,08,21,13,01,14,21,13,
00,05,19,20
M essage =0518,1801,1805,0008,2113,0114,2113,
0005,1920,
C iphertext =1787,2003,2423,0596,0340,1684,0340,
0508,2109,
d, secret decrypt.key=157
1.3.2 Salomaa: "Public-Key Cryptography", ISBN 3-540-61356-0
code, public alphabet=" abcdefghijklmnopqrstuvwxyz", index 0..26
p, secret prime :3336670033
q, secret prime :9876543211
e, public encrypt.key:1031
P laintext :"sauna stoves are hot"
n, public modul =32954765761773295963 (20 Dig, 65 Bit)
E ncoding =19,01,21,14,01,00,19,20,15,22,
05,19,00,01,18,05,00,08,15,20,
M essage =19012114010019201522,05190001180500081520,
C iphertext =25199835365382073661,04085020958227885216,
d, secret decrypt.key=31963885304131991
1.3.3 Stallings: "Cryptography and network security", ISBN 0-13-869017-0
code, public alphabet=" abcdefghijklmnopqrstuvwxyz", index 0..26
p, secret prime :7
q, secret prime :17
e, public encrypt.key:5
P laintext :"stallings"
n, public modul =119 (3 Dig,7 Bit)
E ncoding =19,20,01,12,12,09,14,07,19,
M essage =19,20,01,12,12,09,14,07,19,
C iphertext =066,000,090,001,003,003,025,063,028,066,
d, secret decrypt.key=77