www.r-krell.de |
Webangebot für Schule und Unterricht, Software, Fotovoltaik und mehr |
Willkommen/Übersicht > Informatik > Informatik mit Java, Teil k) > RSA-Demo-Programm
RSA-Programm zur Veranschaulichung der
asymmetrischen Verschlüsslung
bzw. des 'public-key'-Verfahrens nach Rivest, Shamir und
Adleman:
Bedienungsanleitung:
Primzahlen p und q eingeben, n und phi berechnen lassen, e
wählen und prüfen lassen,
d berechnen lassen, Zahl eingeben und ver- oder
entschlüsseln lassen
Bitte Beschränkungen des Zahlbereichs beachten wie im Text
auf der Seite k) dargelegt!
Bitte speichern Sie zunächst die
Programmdatei
RSA_Kryptografie(r-krell.de).jar (15 kB) |
auf Ihrem Computer und starten ("öffnen")
Sie dann die herunter geladene Datei durch Anklicken.
Am besten schieben Sie danach das geöffnete Programmfenster
nach oben links,
sodass Sie gleichzeitig diese Seite lesen können.
Mehr zum Start von Java-Programmen als Application (und nicht mehr als Applet) auf meiner Extraseite Übersicht über meine Java-Programme - Appletprobleme und Downloads, die in einem neuem Browser-Tab geöffnet wird.
Nachfolgend der Quelltext des Java-Programms, soweit
nicht bereits auf der "Informatik-mit-Java"-Seite k)
dargestellt:
zum Inhaltsverzeichnis (oben) / zum Seitenende
// Start der RSA-Oberfläche
// www.r-krell.de/if-java-k.htm ** Krell, 4.2.2011/6.2.2011
public class RSA_0_OberflaechenStart extends javax.swing.JApplet
{
public static void main (String[] s) // Start als Application
{
RSA_0_Oberflaeche rsa = new RSA_0_Oberflaeche("-- als Application");
}
public void init() // Start als Applet
(überflüssig, seit 2017/2020 können Applets nicht
mehr eingesetzt werden)
{
RSA_0_Oberflaeche rsa = new RSA_0_Oberflaeche("-- als Applet");
}
}
zum Inhaltsverzeichnis (oben) / zum Seitenende
** Achtung, Falle: Ich selbst habe das Programm als normale Anwendung (Application) auf meinem Rechner programmiert und getestet. Erst nach dem ersten Veröffentlichungsversuch als Applet musste ich feststellen, dass die z.T. verwendeten Eingabefelder vom Typ JNumberField offenbar in (J)Applets nicht funktionieren. Deshalb musste das Programm so verändert werden, dass alle Felder vom Typ JNumberField als JTextField definiert und erzeugt wurden und dann der neue Quelltext zum Applet kompiliert und zusammengepackt wurde. Hier steht noch der alte, unveränderte Programmtext, um auch den Gebrauch von JNumberField-Objekten zu demonstrieren. Beim DHM-Programm (siehe Sonderseite zum DHM-Applet) ist hingegen der neue Programmtext ohne JNumberField angegeben, um auch das Nachbilden von x = feld .getInt() durch x = Integer.parseInt(feld.getText()); vorzuführen!
Seit 2017 können Applets nicht mehr im Browser
ausgeführt (und seit 2020 auch nicht mehr per Webstart aus
dem Browser heraus angestoßen) werden, sodass Vorkehrungen
für Applets entfallen können. Das hier gezeigte hybrid
programmierte Programm kann aber weiterhin nach dem Herunterladen
der .jar-Datei lokal ausgeführt ("geöffnet") werden -
als Application. **
// RSA-Oberfläche
// www.r-krell.de/if-java-k.htm ** Krell, 4.2.2011/6.2.2011
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class RSA_0_Oberflaeche extends JFrame {
RSA_1_Primzahlsieb pSieb = new RSA_1_Primzahlsieb();
RSA_2_ggT einfacherGgT = new RSA_2_ggT();
RSA_3_dSuche dBerechner = new RSA_3_dSuche();
RSA_4_potMod potMod = new RSA_4_potMod();
// Anfang Attribute
private JLabel jLabel1 = new JLabel();
private JLabel jLabel2 = new JLabel();
private JButton jBtPrimzahlenZeigen = new JButton();
private JLabel jLabel3 = new JLabel();
private JNumberField jNf_p = new JNumberField();
private JLabel jLabel4 = new JLabel();
private JNumberField jNf_q = new JNumberField();
private JLabel jLabel5 = new JLabel();
private JButton jBt_n_phi_berechnen = new JButton();
private JLabel jLabel6 = new JLabel();
private JNumberField jNf_n = new JNumberField();
private JLabel jLabel7 = new JLabel();
private JNumberField jNf_phi = new JNumberField();
private JLabel jLabel8 = new JLabel();
private JLabel jLabel9 = new JLabel();
private JNumberField jNf_e = new JNumberField();
private JButton jBt_ggT = new JButton();
private JButton jBt_d = new JButton();
private JLabel jLabel10 = new JLabel();
private JTextField jTf_ggT = new JTextField();
private JLabel jLabel11 = new JLabel();
private JNumberField jNf_d = new JNumberField();
private JLabel jLabel12 = new JLabel();
private JLabel jLabel13 = new JLabel();
private JLabel jLabel14 = new JLabel();
private JTextField jTf_k = new JTextField();
private JButton jBt_Verschluesseln = new JButton();
private JLabel jLabel15 = new JLabel();
private JTextField jTf_g = new JTextField();
private JButton jBt_Entschluesseln = new JButton();
private JScrollPane jScrollPane1 = new JScrollPane();
private JTextArea jTA_Ausgabe = new JTextArea("");
private JLabel jLabel16 = new JLabel();
// Ende Attribute
public RSA_0_Oberflaeche (String title) {
super ("RSA-Kryptografie (www.r-krell.de) "+title);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
int frameWidth = 729;
int frameHeight = 622;
setSize(frameWidth, frameHeight);
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width) / 2;
int y = (d.height - getSize().height) / 2;
setLocation(x, y);
Container cp = getContentPane();
cp.setLayout(null);
// Anfang Komponenten
jLabel1.setBounds(24, 16, 141, 24);
jLabel1.setText("RSA-Verfahren");
jLabel1.setFont(new Font("MS Sans Serif", Font.BOLD, 17));
cp.add(jLabel1);
jLabel2.setBounds(24, 48, 204, 16);
jLabel2.setText("1) Wahl zweier 'großer' Primzahlen");
jLabel2.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel2);
jBtPrimzahlenZeigen.setBounds(280, 40, 145, 25);
jBtPrimzahlenZeigen.setText("Primzahlen zeigen");
jBtPrimzahlenZeigen.setMargin(new Insets(2, 2, 2, 2));
jBtPrimzahlenZeigen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jBtPrimzahlenZeigen_ActionPerformed(evt);
}
});
cp.add(jBtPrimzahlenZeigen);
jLabel3.setBounds(456, 48, 15, 16);
jLabel3.setText("p=");
jLabel3.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel3);
jNf_p.setBounds(480, 40, 73, 24);
jNf_p.setText("13");
cp.add(jNf_p);
jLabel4.setBounds(592, 48, 15, 16);
jLabel4.setText("q=");
jLabel4.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel4);
jNf_q.setBounds(616, 40, 73, 24);
jNf_q.setText("19");
cp.add(jNf_q);
jLabel5.setBounds(24, 96, 244, 16);
jLabel5.setText("2) n=p*q und phi=(p-1)*(q-1) berechnen");
jLabel5.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel5);
jBt_n_phi_berechnen.setBounds(280, 88, 145, 25);
jBt_n_phi_berechnen.setText("n und phi berechnen");
jBt_n_phi_berechnen.setMargin(new Insets(2, 2, 2, 2));
jBt_n_phi_berechnen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jBt_n_phi_berechnen_ActionPerformed(evt);
}
});
cp.add(jBt_n_phi_berechnen);
jLabel6.setBounds(456, 96, 17, 16);
jLabel6.setText("n=");
jLabel6.setFont(new Font("MS Sans Serif", Font.BOLD, 13));
cp.add(jLabel6);
jNf_n.setBounds(480, 88, 73, 24);
jNf_n.setText("");
jNf_n.setEditable(false);
cp.add(jNf_n);
jLabel7.setBounds(584, 96, 25, 16);
jLabel7.setText("phi=");
jLabel7.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel7);
jNf_phi.setBounds(616, 88, 73, 24);
jNf_phi.setText("");
jNf_phi.setEditable(false);
cp.add(jNf_phi);
jLabel8.setBounds(24, 144, 390, 16);
jLabel8.setText("3) e für öffentlichen Schlüssel wählen (e < phi mit ggT(e,phi) = 1)");
jLabel8.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel8);
jLabel9.setBounds(40, 176, 18, 16);
jLabel9.setText("e=");
jLabel9.setFont(new Font("MS Sans Serif", Font.BOLD, 13));
cp.add(jLabel9);
jNf_e.setBounds(72, 168, 81, 24);
jNf_e.setText("5");
cp.add(jNf_e);
jBt_ggT.setBounds(280, 168, 145, 25);
jBt_ggT.setText("nur ggT prüfen");
jBt_ggT.setMargin(new Insets(2, 2, 2, 2));
jBt_ggT.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jBt_ggT_ActionPerformed(evt);
}
});
cp.add(jBt_ggT);
jBt_d.setBounds(456, 168, 233, 25);
jBt_d.setText("d für privaten Schlüssel berechnen");
jBt_d.setMargin(new Insets(2, 2, 2, 2));
jBt_d.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jBt_d_ActionPerformed(evt);
}
});
cp.add(jBt_d);
jLabel10.setBounds(280, 208, 69, 16);
jLabel10.setText("ggT(phi,e)=");
jLabel10.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel10);
jTf_ggT.setBounds(360, 200, 65, 24);
jTf_ggT.setText("");
jTf_ggT.setEditable(false);
cp.add(jTf_ggT);
jLabel11.setBounds(456, 208, 15, 16);
jLabel11.setText("d=");
jLabel11.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel11);
jNf_d.setBounds(480, 200, 73, 24);
jNf_d.setText("");
jNf_d.setEditable(false);
cp.add(jNf_d);
jLabel12.setBounds(24, 240, 452, 16);
jLabel12.setText("4) Nur n und e veröffentlichen (aber p, q, phi und d sicher geheim halten!)");
jLabel12.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel12);
jLabel13.setBounds(24, 272, 366, 16);
jLabel13.setText("5) Verschlüsseln (g = k^e %n) oder Entschlüsseln (k = g^d %n)");
jLabel13.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel13);
jLabel14.setBounds(40, 304, 22, 16);
jLabel14.setText("k=");
jLabel14.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel14);
jTf_k.setBounds(72, 296, 81, 24);
jTf_k.setText("65");
cp.add(jTf_k);
jBt_Verschluesseln.setBounds(280, 296, 145, 25);
jBt_Verschluesseln.setText("Verschlüsseln");
jBt_Verschluesseln.setMargin(new Insets(2, 2, 2, 2));
jBt_Verschluesseln.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jBt_Verschluesseln_ActionPerformed(evt);
}
});
cp.add(jBt_Verschluesseln);
jLabel15.setBounds(40, 344, 23, 16);
jLabel15.setText("g=");
jLabel15.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel15);
jTf_g.setBounds(72, 336, 81, 24);
jTf_g.setText("");
cp.add(jTf_g);
jBt_Entschluesseln.setBounds(280, 336, 145, 25);
jBt_Entschluesseln.setText("Entschlüsseln");
jBt_Entschluesseln.setMargin(new Insets(2, 2, 2, 2));
jBt_Entschluesseln.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jBt_Entschluesseln_ActionPerformed(evt);
}
});
cp.add(jBt_Entschluesseln);
jScrollPane1.setBounds(24, 392, 665, 177);
cp.add(jScrollPane1);
jTA_Ausgabe.setBounds(-74, -2, 737, 177);
jTA_Ausgabe.setText("");
jTA_Ausgabe.setLineWrap(true);
jScrollPane1.setViewportView(jTA_Ausgabe);
jLabel16.setBounds(520, 344, 190, 16);
jLabel16.setText(" R. Krell (www.r-krell.de)");
jLabel16.setFont(new Font("MS Sans Serif", Font.PLAIN, 13));
cp.add(jLabel16);
// Ende Komponenten
setResizable(false);
setVisible(true);
}
// Anfang Methoden
public void jBtPrimzahlenZeigen_ActionPerformed(ActionEvent evt) {
jTA_Ausgabe.append(pSieb.gibText(160)+"\n");
}
public void jBt_n_phi_berechnen_ActionPerformed(ActionEvent evt) {
jNf_n.setInt(-1);
jNf_phi.setInt(-1);
int p = jNf_p.getInt();
int q = jNf_q.getInt();
jNf_n.setInt(p*q);
jNf_phi.setInt((p-1)*(q-1));
jNf_d.setText("");
if (p*q >= Math.sqrt(Integer.MAX_VALUE))
{
jTA_Ausgabe.append("** Achtung: n >= "+(int)(Math.sqrt(Integer.MAX_VALUE))
+ ". Interne Zwischenergebnisse beim Ver- und Entschlüsseln können mit max.\n"
+ "n*n zu unbemerktem Ganzzahl-Überlauf und damit zu falschen Ergebnissen für g bzw. k führen! **\n");
}
}
public void jBt_ggT_ActionPerformed(ActionEvent evt) {
jTf_ggT.setText(" ?");
int e = jNf_e.getInt();
int phi = jNf_phi.getInt();
jTf_ggT.setText(""+einfacherGgT.ggT_rek(phi, e));
}
public void jBt_d_ActionPerformed(ActionEvent evt) {
jNf_d.setInt(-1);
int p = jNf_p.getInt();
int q = jNf_q.getInt();
int e = jNf_e.getInt();
jNf_d.setInt(dBerechner.sucheD(p,q,e));
// System.out.println("d (ErwEuklA) = "+dBerechner.sucheD(p,q,e)+", d (Prob) = "+dBerechner.sucheD_v1(p,q,e));
}
public void jBt_Verschluesseln_ActionPerformed(ActionEvent evt) {
jTf_g.setText(" ?");
String kWort = jTf_k.getText();
int n = 1;
int e = -1;
try
{
n = jNf_n.getInt();
e = jNf_e.getInt();
}
catch (NumberFormatException nfe)
{ }
if (e <= 1)
{
jTA_Ausgabe.append("** Ohne p, q, n (<-bitte erst berechnen lassen!) und e kein Verschlüsseln möglich! **\n");
}
else
{
int k = 0;
try
{
k = Integer.parseInt(kWort);
}
catch (Exception ex)
{
k = (int)(kWort.charAt(0));
jTA_Ausgabe.append("Aus der Eingabe k="+kWort+" wurde der ASCII-Wert "+k+" des vordersten Zeichens bestimmt!\n");
}
int g = potMod.potMod(k,e,n);
jTf_g.setText(""+g);
}
}
public void jBt_Entschluesseln_ActionPerformed(ActionEvent evt) {
jTf_k.setText(" ?");
String gWort = jTf_g.getText();
int n = 1;
int d = -1;
try
{
n = jNf_n.getInt();
d = jNf_d.getInt();
}
catch (NumberFormatException e)
{ }
if (d<1)
{
jTA_Ausgabe.append("** Ohne p, q, n und d (<-bitte erst berechnen lassen!) kein Entschlüsseln möglich! **\n");
}
else
{
int g = 0;
try
{
g = Integer.parseInt(gWort);
}
catch (Exception ex)
{
g = (int)((gWort).charAt(0));
jTA_Ausgabe.append("Aus der Eingabe g="+gWort+" wurde der ASCII-Wert "+g+" des vordersten Zeichens bestimmt!\n");
}
int k = potMod.potMod(g,d,n);
jTf_k.setText(""+k);
}
}
}
zum Inhaltsverzeichnis (oben) / zum Seitenende
Hinweis: Die Klassen RSA_1_Primzahlsieb, RSA_2_ggT und RSA_3_dSuche sind unter gleichen Namen auf der Seite k) im Quelltext angegeben. Die Klasse RSA_4_potMod ist (bis auf den Namen) identisch mit der auf der Seite k) vorgestellten Klasse RestVonPotenz_Rechner
zurück zur
Seite „Informatik mit Java, Teil k)"