Hallo,
ich habe die DES-Verschlüsselung in Java (Compiler BlueJ) implementiert. Allerdings hat sich ein Fehler eingeschlichen, welchen ich auch nach Stundenlanger suche nicht finden konnte. (lässt sich compilieren, aber die ASCII werte beim Decodieren stimmen nicht)
Ich hoffe hier findet wer den Fehler.
Codieren:
ich habe die DES-Verschlüsselung in Java (Compiler BlueJ) implementiert. Allerdings hat sich ein Fehler eingeschlichen, welchen ich auch nach Stundenlanger suche nicht finden konnte. (lässt sich compilieren, aber die ASCII werte beim Decodieren stimmen nicht)
Ich hoffe hier findet wer den Fehler.
Codieren:
Java:
//Includes
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//Main-Klasse
public class Codierer extends JFrame implements ActionListener
{
//GUI-Variablen
private JLabel lStatus, lKlartext, lGeheimtext, lKey;
private JTextField tKey;
private JTextArea tKlartext, tGeheimtext;
private JButton bCodiere;
//---- Initialisierung ------------------------------------------------
public Codierer()
{
//---- GUI --------------------------------------------------------
.... benutz ich immer muss Fehlerfrei sein^^
//-----------------------------------------------------------------
}
//---------------------------------------------------------------------
//---- Button-Abfrage -------------------------------------------------
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==bCodiere)
{
MainCodiere();
}
}
//---------------------------------------------------------------------
//---- Die erste Codier Klasse ----------------------------------------
public void MainCodiere()
{
String sKey = tKey.getText(); //String wird mit dem key gefüllt
//führt die klasse mit dem Paritäts-check aus
if(MakePariCheck(sKey) == false)
{
//wenn die Paritäts-klasse false liefert stimmen die Bits nicht
lStatus.setText("Key: Paritätsbits nicht korrekt!");
}
else
{
//Überprüfung gelungen! Zweite Codier Klasse wird ausgeführt
lStatus.setText("Wird verschluesselt");
SubCodiere(sKey);
}
}
//-----------------------------------------------------------------------
//---- Paritäts-Check Klasse --------------------------------------------
public boolean MakePariCheck(String sKey)
{
boolean checked = false; //return statement standardmäßig auf false
int counter1 = 0; //zählt die anzahl der gelungen Paritätsbits
String buffer[] = new String[8]; //String Array zum speichern der 8 bausteine
for(int i = 0; i<8; i++) //bausteine werden durchlaufen
{
buffer[i] = sKey.substring(i*8 ,i*8 + 8); //bausteine werden einzeln gepseichert
int counter2 = 0; //Anzahl der 1er im baustein
for(int j = 0; j<8; j++) //Baustein wird durchlaufen
{
if(buffer[i].charAt(j) == '1') //1 gefunden
{
counter2++; //counter für die 1er um 1 erhöht
}
}
if(counter2%2 == 0) //wenn die 1er durch 2 teilbar sind
{
counter1++; //Gelungen! block Paritätsbit stimmt
}
}
if(counter1 == 8) //Wenn alle Paritätsbits stimmen
{
checked = true; //checked = true setzten
}
return checked; //Ergebnis zurückliefern
}
//---- Zweite Instanz der Codierung ----------------------------------
public void SubCodiere(String sKey)
{
String sKlartext = tKlartext.getText(); //der Klartext wird als String gespeichert
//Solange der Klartext nicht durch 8 teilbar ist leerzeichen anfügen
while(sKlartext.length()%8 != 0)
{
sKlartext = sKlartext + " ";
}
//Solange der Klartext noch zeichen beinhaltet
while(sKlartext.length() > 0)
{
String sBuffer = ""; //Buffer erstellen
String block = ""; //Block erstellen
sBuffer = sKlartext.substring(0,8); //Block mit den ersten 8 zeichen füllen
sKlartext = sKlartext.substring(8, sKlartext.length()); //Block vom klartext abziehen
//Durchläuft den Block
for(int i = 0; i<8; i++)
{
int iBuffer; //speichert die ASCII werte
String binary; //speichert die ASCII werte als String
iBuffer = (int)sBuffer.charAt(i); //ASCII wert wird ausgelesen
System.out.println(iBuffer);
binary = Integer.toBinaryString(iBuffer); //und als Binär string gespeichert
System.out.println(binary);
//füllt den BinärString auf, falls die Zahl zu klein war
while(binary.length() < 8)
{
binary = "0" + binary;
}
block = block + binary; //fügt alle Binärstrings zusammen
}
System.out.println(block);
//Der Block und der Key werden in die zweite UnterInstanz der Codierung geschickt
SubCodiere2(block,sKey);
}
}
//---- Zweite Unterinstanz der Codierung ---------------------------
/*
* -Die eigentliche DES-Verschlüsselung
* -Der Block wird der IP unterzogen
* -Der Key wird der PC-1 unterzogen
* -Der Key wird in lKey und rKey unterteilt
* -Block wird in rBlock und lBlock unterteilt
* -die 16 runden werden durchgeführt
* -Keys werden verschoben
* -Key wird Permutation 2 unterzogen
* -Der lBlock wird mit dem rundenKey in die FunktionF geschickt
* -lBlock und rBlock werden getauscht
* -In der letzten runde bleiben die Blöcke an ihrer Stelle
* -Der lBlock und rBlock werden zum Block wieder zusamengefügt
* -Der Block wird der FP unterzogen
* -Der Block wird an das gesamtergebnis angefügt
*/
public void SubCodiere2(String block, String key)
{
block = IP(block); //Block wird der IP unterzogen
String roundKey = PCone(key); //roundKey wird der PC-1 unterzogen
String lKey = roundKey.substring(0,28); //lKey wird aus dem roundKey gesplittet
String rKey = roundKey.substring(28,56); //rKey wird aus dem roundKey gesplittet
String lBlock = block.substring(0,32); //lBlock wird aus dem Block gesplittet
String rBlock = block.substring(32,64); //rBlock wird aus dem BLock gesplittet
String result = ""; //Ergebnis string
//Die 16 Runden
for(int i = 0; i<16; i++)
{
String buffer; //buffer für den switch von l und rBlock
rKey = Shift(rKey, i); //rKey wird geshiftet
lKey = Shift(lKey, i); //lKey wird geshiftet
roundKey = lKey + rKey; //roundKey wird aus lKey und rKey zusammengesetzt
roundKey = PCtwo(roundKey); //roundKey wird der PC-2 unterzogen
buffer = FunktionF(lBlock, roundKey); //FunktionF wird mit lBlock und roundKey durchgeführt
buffer = XOR(rBlock, buffer); //XOR mit dem Erebnis der FunktionF und dem rBlock
//fals nicht runde 15 Blöcke tauschen
if(i != 15)
{
rBlock = lBlock; //neuer rBlock = alter lBlock
lBlock = buffer; //neuer lBlock = ergebnis aus dem XOR
}
else
{
rBlock = buffer; //in der letzen runde bleibt der rBlock der rBlock!
}
}
result = lBlock + rBlock; //Ergebnis wird aus l und rBlock zusammengefügt
result = FP(result); //Ergebnis wird der FP unterzogen
tGeheimtext.setText(tGeheimtext.getText() + result); //Ergebnis wird an den Geheimtext angefügt
}
//---- IP ------------------------------------------------------------
public String IP(String block)
{
String buffer = ""; //buffer wird erstellt
int iIP[] = {58,50,42,34,26,18,10,2,
60,52,55,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7}; //die Stellen der IP als int-Array
//der buffer wird gefüllt
for(int i = 0; i<64; i++)
{
buffer = buffer + block.charAt(iIP[i]-1); //der Int-Array gibt die neue Position des Ergebnisses an
}
return buffer; //buffer wird zurückgegeben
}
//---- FP --------------------------------------------------------------
public String FP(String block)
{
String buffer = "";
int iFP[] = {40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41,9,49,17,57,25};
for(int i = 0; i<64; i++)
{
buffer = buffer + block.charAt(iFP[i]-1);
}
return buffer;
}
//---- PC-1 --------------------------------------------------------------
public String PCone(String key)
{
String buffer = "";
int PCone[] = {57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4}; //<- bits 8,16,24,32,40,48,56,64 fehlen
for(int i = 0; i<56; i++) //<- nur 56 Stellen!
{
buffer = buffer + key.charAt(PCone[i]-1);
}
return buffer;
}
//---- PC-2 ---------------------------------------------------------------
public String PCtwo(String key)
{
String buffer = "";
int PCtwo[] = {14,17,11,24,1,5,
3,28,15,6,21,10,
23,19,12,4,26,8,
16,7,27,20,13,2,
41,52,31,37,47,55,
30,40,51,45,33,48,
44,49,39,56,34,53,
46,42,50,36,29,32}; //<- einige Stellen fehlen
for(int i = 0; i<48; i++) //<- nur 48 Stellen!
{
buffer = buffer + key.charAt(PCtwo[i]-1);
}
return buffer;
}
//---- Verschiebungs Funktion -----------------------------------------------
public String Shift(String Key, int round)
{
int iShift[] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
char buffer[] = new char[28];
for(int i = 0; i<iShift[round]; i++) //je nach Runde wird 1 oder 2 mal verschoben
{
buffer[27] = Key.charAt(0); //letzte stelle wird mit der ersten gefüllt
for(int j = 0; j<27; j++) //läuft den Key durch
{
buffer[j] = Key.charAt(j+1); //speichert den Key um 1 verschoben
}
String kBuffer = new String(buffer); //der Buffer-Array wird als String gespeichert
Key = kBuffer; //der Buffer-String wird zum neuen Key
}
return Key; //gibt den Key zurück
}
//---- Die Funktion F --------------------------------------------------------
/*
* -erstellt einen buffer und einen rückgabe String
* -Der Block wird der EP unterzogen
* -Mit dem Block und dem Key wird ein XOR durchgeführt, das Ergebniss wird im Buffer gepseichert
* -Der Buffer wird in einzelne Strings zerlegt und in die Boxen geschickt
* -Das Ergebnis der Boxen wird an den rückgabe String angefügt
* -Der rückgabe String wird der Permutation P unterzogen
*/
public String FunktionF(String block, String key)
{
String buffer = ""; //Bufer erstellen
String back = ""; //Rückgabewert erstellen
block = EP(block); //Block wird der EP unterzogen
buffer = XOR(block, key); //XOR wird mit dem Block und dem Key durchgeführt
//buffer wird in 8 Teile zerlegt
for(int i = 0; i<8; i++)
{
String s = buffer.substring(i*6,i*6+6); //neue Strings aus dem Buffer á 6 stellen
s = Box(s,i+1); //Strings werden in die Betrefenden Boxen geschickt
back = back+s; //Strings werden an den Rückgabe String angefügt
}
back = P(back); //Rückgabe String wird P unterzogen
return back;
}
//---- XOR-Funktion ------------------------------------------------------------
public String XOR(String NumOne, String NumTwo)
{
String sBuffer = ""; //Ergebnis-Buffer wird erstellt
long lOne, lTwo, lResult; //Longs werden erstellt
lOne = Long.valueOf(NumOne, 2); //String 1 wird als long gepseichert
lTwo = Long.valueOf(NumTwo, 2); //String 2 wird als long gepseichert
lResult = lOne ^ lTwo; //XOR mit den beiden longs
sBuffer = Long.toBinaryString(lResult); //Ergebnis-buffer wird mit dem Brinär-long Ergebnis gefüllt
while(sBuffer.length() < NumOne.length()) //Nullen einfügen fals nötig
{
sBuffer = "0" + sBuffer;
}
return sBuffer;
}
//---- EP ----------------------------------------------------------------------
public String EP(String block)
{
String buffer = "";
int EP[] = {32,1,2,3,4,5,
4,5,6,7,8,9,
8,9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32,1}; //<- Einige Bit-Stellen sind doppelt vertreten
for(int i = 0; i<48; i++) //aus 32-Bits werden 48 Bits!
{
buffer = buffer + block.charAt(EP[i]-1);
}
return buffer;
}
//---- P -------------------------------------------------------------------------
public String P(String block)
{
String buffer = "";
int P[] = {16,7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2,8,24,14,
32,27,3,9,
19,13,30,6,
22,11,4,25};
for(int i = 0; i<32; i++)
{
buffer = buffer + block.charAt(P[i]-1);
}
return buffer;
}
//---------------------------------------------------------------------------------
//---- Die S-Boxen ----------------------------------------------------------------
/*
* -es werden Counter für die Zeilen und die Spalten der Tabelle erstellt
* -Der erste und der letzte Bit des eingegangenen Strings geben die Zeile an
* -Die mittleren vier Bits geben die Spalte an
* -die Stelle ausgelesen
* -Das Ergebnis wird in einen Binär-String convertiert
* -fals die Nummer zu klein war, werden die nötigen 0en angehängt
*
* -Kommentare gibt es nur an Box 1 die anderen funktionieren analog
*/
public String Box(String buffer, int number)
{
String result = ""; //Ergebnis String
int counter1 = 0; //Counter für die Zeile
int counter2 = 0; //Counter für die Spalte
//Zeile wird bestimmmt
if(buffer.charAt(0) == '0' && buffer.charAt(5) == '0'){counter1 = 0;}
else if(buffer.charAt(0) == '0' && buffer.charAt(5) == '1'){counter1 = 1;}
else if(buffer.charAt(0) == '1' && buffer.charAt(5) == '0'){counter1 = 2;}
else{counter1 = 3;}
//Spalte wird binär zusammen gerechnet
if(buffer.charAt(1) == '1'){counter2 = counter2 + 8;}
if(buffer.charAt(2) == '1'){counter2 = counter2 + 4;}
if(buffer.charAt(3) == '1'){counter2 = counter2 + 2;}
if(buffer.charAt(4) == '1'){counter2 = counter2 + 1;}
//Box nummer (wird übergeben)
if(number == 1)
{
//Zeilen nummer (wurde bestimmt)
if(counter1 == 0)
{
int iBuffer[] = {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7}; //Die Zeile 0 in Box 1
//der Counter2 gibt die Spalte an(Ergebnis wird direkt binär gespeichert)
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8}; //Die Zeile 1 in Box 1
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0}; //Die Zeile 2 in Box 1
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}; //Die Zeile 3 in Box 1
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 2)
{
if(counter1 == 0)
{
int iBuffer[] = {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 3)
{
if(counter1 == 0)
{
int iBuffer[] = {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 4)
{
if(counter1 == 0)
{
int iBuffer[] = {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 5)
{
if(counter1 == 0)
{
int iBuffer[] = {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 6)
{
if(counter1 == 0)
{
int iBuffer[] = {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 7)
{
if(counter1 == 0)
{
int iBuffer[] = {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
if(number == 8)
{
if(counter1 == 0)
{
int iBuffer[] = {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 1)
{
int iBuffer[] = {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 2)
{
int iBuffer[] = {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8};
result = Integer.toBinaryString(iBuffer[counter2]);
}
else if(counter1 == 3)
{
int iBuffer[] = {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11};
result = Integer.toBinaryString(iBuffer[counter2]);
}
}
//fals die Zahl zu klein war werden 0en angefügt
for(int i = 0; i<3; i++)
{
if(result.length() < 4)
{
result = "0" + result;
}
}
return result;
}
}