26.4
Implementierung von RSA |
|
Ein Blick
in die API zeigt, dass in der Klasse
BigInteger eine Methode
modPow(...)
implementiert ist, die die Programmierung von RSA erheblich erleichtert.
Sie führt die mathematische Operation c = me mod n mit m als Originalkode und c Geheimkode aus. |
|
![]() |
|
Dabei entspricht dem
exponent
in der Parameterliste das e in der Formel, und dem
m
in der Parameterliste entspricht das n in der Formel. Die Basis m in ist
dann das BigInteger-Objekt,
für das die Methode aufgerufen wird. Der Rückgabewert, wieder ein
BigInteger-Objekt,
entspricht dann dem c. Für die am Anfang von Kap. 26.1 RSA verwendeten Werte (n= 2773, e = 17 und m 920), heißt unser Programm |
|
Download: RSAEnCrypt2.java |
import info1.*; import java.math.*; public class RSAEnCrypt2{ public static void main(String[] args){ String n = "2773"; String e = "17"; String m = "920"; BigInteger nBig = new BigInteger(n); BigInteger eBig = new BigInteger(e); BigInteger mBig = new BigInteger(m); BigInteger cBig = mBig.modPow(eBig,nBig); String c = cBig.toString(); System.out.println("Geheimtext: "+c); } } Ausgabe: Geheimtext: 948 |
Download: RSADeCrypt2.java |
import info1.*; import java.math.*; public class RSADeCrypt2{ public static void main(String[] args){ String n = "2773"; String d = "157"; String c = "948"; BigInteger nBig = new BigInteger(n); BigInteger dBig = new BigInteger(d); BigInteger cBig = new BigInteger(c); BigInteger mBig = cBig.modPow(dBig,nBig); String m = mBig.toString(); System.out.println("Geheimtext: "+m); } } Ausgabe: Geheimtext: 920 |
Wir haben
damit alle Voraussetzungen um unsere RSA-Methode
rsa(String originalText, int n, int e): String für die Klasse EnCrypt und rsa(String geheimText, int n, int d): String für die Klasse
DeCrypt
zu implementieren. |
|
Download: EnCrypt.java |
public static String rsa(String originalText, int n, int e){ //Das Ensemle (n,e) stellt den public key des RSA- //Verfahrens dar. String geheimText = ""; java.math.BigInteger nBig = new java.math.BigInteger(""+n); java.math.BigInteger eBig = new java.math.BigInteger(""+e); java.math.BigInteger mBig; int c; for (int i = 0; i < originalText.length(); i++){ mBig = new java.math.BigInteger(""+ (int)originalText.charAt(i)); c = mBig.modPow(eBig,nBig).intValue(); geheimText += (char)c; } return geheimText; } |
Bemerkungen |
Da die Klasse EnCrypt nur in der
rsa-Methode das Paket java.math verwendet, wurde dieses Paket nicht durch
einen import
zur Verfügung gestellt, sondern der Paketname wurde dem Klassenname
vorgestellt. Der Konstruktor, den wir für die Erzeugung der
BigInteger-Objekte
verwenden, verlangt einen String
als Übergabeparamter. Deshalb wurde die
int-Variablen
n und e mit ""+n
und ""+e
also mit Hilfe einer Konkatenation mit einem leeren
String
zu String-Objekten.
Entsprechend erhalten wir für die
rsa(...)-Methode
in DeCrypt. |
Download: DeCrypt.java |
public static String rsa(String geheimText, int n, int d){ //Das Ensemle (n,d) stellt den private key des RSA- //Verfahrens dar String originalText = ""; java.math.BigInteger nBig = new java.math.BigInteger(""+n); java.math.BigInteger dBig = new java.math.BigInteger(""+d); java.math.BigInteger cBig; int m; for (int i = 0; i < geheimText.length(); i++){ cBig = new java.math.BigInteger(""+ (int)geheimText.charAt(i)); m = cBig.modPow(dBig,nBig).intValue(); originalText += (char)m; } return originalText; } |
TestProgramm Download: rsaTest.java |
public class rsaTest { public static void main (String[] args) { int n = 2773; int e = 17; int d = 157; String originalText = "Michael Pohlig"; String geheimText = EnCrypt.rsa(originalText,n,e); System.out.println(geheimText); String entschluesselt = DeCrypt.rsa(geheimText,n,d); System.out.println(entschluesselt); } } Ausgabe: ???┴??®???┴®?? Michael Pohlig |
Bemerkungen |
Geben wir in diesem Programm für
n = 2773, e = 17
und für den Originaltext
"920"
ein, so erhalten wir für den Geheimtext natürlich nicht mehr wie oben
"948", den jetzt werden nicht mehr der Wert 920 verschlüsselt, sondern die
Bytekodes, die zu den Zeichen 9, 2 und 0 gehören.
|
Das ist noch nicht alles |
Nun hat unsere RSA-Verschlüsselung
einen gravierenden Nachteil. Da wir immer
byte
für byte,
also Buchstabe für Buchstabe verschlüsselt haben, haben wir unsere
Verschlüsselung zu einer monoalphabetischen Substitution degradiert. Mit
einer Häufigkeitsanalyse ließe sich der Geheimtext leicht entschlüsseln
und alle Mühe war umsonst. Wir sollten also eine Blocklänge größer
als 8 bit wählen. Damit stellt sich aber die Frage nach dem Zusammenhang
zwischen der Blocklänge und der Zahl n. Dass dies Frage nicht
nebensächlich ist, lässt sich so einsehen: Ist etwa ein Block 8 bit lang,
so ist die Anzahl der möglichen Zeichen in diesem Block, also das Alphabet
des Originaltextes, durch 28 = 256 begrenzt. Das Alphabet des
Geheimtextes muss also mindestens 256 Zeichen enthalten. Wegen c = me
mod n muss n mindestens 256 sein, den eine Operation
x mod 256
kann genau 256 verschiedene Zeichen liefern. Wählen wir nämlich n kleiner,
so gibt es Zeichen m1 ≠
m2 aus dem
Originalalphabet, die gleich verschlüsselt werden, also c1=c2.
Eine Entschlüsselung wäre somit nicht mehr eindeutig.
In unserem letzten Beispiel hatten wir n = 2773 setzen, so können wir wegen "Anzahl der bit-Blöcke" ≤ log22773 = 11,44 höchstens 11-bit-lange Blöcke verschlüsseln. In der Praxis werden 1024-bit-Blöcke verschlüsselt. |
zu | 26.5 Übungen und Vertiefung: RSA |
zur Startseite | www.pohlig.de (C) MPohlig 2006 |