23.20 Implementierung von RSA in EnKrypt und DeKrypt
 
Die Klasse BigInteger

 

Download:
BigIntegerTest1. java

 

 

 

 

 

Ergebnis mit Hilfe des CAS-Systems Mathematica berechnet.

Textdatei, in der das Java-Ergebnis gespeichert ist.

 

Java hat im Paket java.math eine Klasse mit dem Namen BigInteger implementiert. Objekte dieser Klasse sind in ihrer Größe so angepasst, dass sie Ganzzahlen von der Größe aufnehmen, wie sie eine Rechenoperation liefert. Testen Sie dazu das folgende Programm:
import java.math.*;
public class BigIntegerTest1 {

  public static void main (String[] args) {

     BigInteger zahl1 = new BigInteger("12345678965");
     int zahl2 = 12345;
     String potenz = zahl1.pow(zahl2).toString();
     System.out.println(potenz);
  }
}

Wundern Sie sich aber nicht, wenn es eine geraume zeit dauert, bis das Programm mit der Ausgabe beginnt.
Das kleine Testprogramm zeigt uns nebenbei, wie man den für unsere Zwecke geeigneten Konstruktor benutzt. Die Zahl, die wir als ein Groß-Integer-Zahl verwenden wollen, übergeben wir dem Konstruktor in einer Zeichenkette. Die Objektmethode
pow(...) hat die Signatur

pow(int exponent): BigInteger

und wird für ein BigInteger-Objekt aufgerufen. In unserem Programm wird 1234567896512345 exakt berechnet! Das gelieferte Ergebnis (ein BigInteger-Objekt lässt sich mittels der Methode toString() konvertieren und in einem String-Objekt ablegen. Da das Ergebnis - 124 580 Stellen - nicht vollständig in einem Windows Ein/Ausgabefenster dargestellt wird, wird hier eine Textdatei angeboten, die die ganze Zahl aufzeigt.
 

Downlaod:
BigIntegerTest2. java
Für Interessierte: Der Download bietet das Programm, das die Zahl in eine Textdatei speichert und auch die Anzahl der Stellen hinter dem Komma bestimmt.
 
  Ein Blick in die API zeigt, dass es in der Klasse BigInteger eine Methode modPow(...) gibt, die unsere Verschlüsselung auf einen Schlag macht. Wir müssen lediglich die Datenkonvertierung noch vornehmen.
 
 
Für die am Anfang von Kap.  23.19 RSA verwendeten Werte, heißt unser Programm
Download:
RSAEnkrypt.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:
RSADekrypt2.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 EnKrypt und

   rsa(String geheimText, int n, int d): String

für die Klasse DeKrypt zu implementieren.
 

Download:
EnKrypt.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 EnKrypt 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 DeKrypt.
 
Download:
DeKrypt.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 = EnKrypt.rsa(originalText,n,e);
     System.out.println(geheimText);
     String entschluesselt = DeKrypt.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. 

Schließlich müssen wir noch anmerken, dass sich 'unsere' RSA-Verschlüsselung von der professionellen nicht nur in der Größe der verwendeten Schlüssel unterscheidet, sondern auch darin, dass beim professionellen Verschlüsseln nicht Buchstabe für Buchstabe chiffriert wird sondern ganze Blöcke.
 

zu 23.21 Übungen zu RSA
zur Startseite www.pohlig.de  (C) MPohlig 2005