DES, eine der gängigen Schlüsselverschlüsselungsmethoden, verwendet eine Struktur, die als Fistelnetzwerk bezeichnet wird. Kurz gesagt handelt es sich um eine Verschlüsselungsmethode, die eine Funktion verwendet, die als Rundungsfunktion bezeichnet wird, und eine exklusive logische Summe. In DES gibt es die Regel, dass der Klartext der Eingabe 64 Bit und die Bitlänge des Schlüssels 56 Bit beträgt. Dieses Mal wollte ich jedoch nur ein Fistelnetzwerk implementieren, sodass solche Einschränkungen ausgeschlossen sind.
[Referenz] Erklärung der Feistel-Struktur in Wikipedia
Der hier veröffentlichte Code ist auf GitHub veröffentlicht, der unten verlinkt ist. feistelNetwork
Main.java
package main;
import common.AbstractEncryption;
import encryption.Decryption;
import encryption.Encryption;
public class Main {
//Anzahl der Runden
public static int ROUND_EXEC_TIME = 3;
//Privater Schlüssel für die Rundungsfunktion
//Da die Rundungsfunktion eine Bitverschiebungsoperation ausführt, kann sie nur verschlüsselt werden, wenn eine Zahl kleiner als 8 angegeben ist.
//Dieser Schlüssel muss geheim gehalten werden, damit er nicht von einem Angreifer geknackt wird
private static int[] SECRET_KEY = {2, 3, 6};
public static void main(String[] args) {
//Vertrauliche Daten
String secretData = "testcase";
AbstractEncryption encryption = new Encryption();
AbstractEncryption decryption = new Decryption();
//Verschlüsselung
String encryptionData = encryption.execEncryption(secretData, SECRET_KEY);
//Entschlüsselung
String deryptionData = decryption.execEncryption(encryptionData, SECRET_KEY);
System.out.println("Verschlüsselte Daten:" + encryptionData);
System.out.println("Entschlüsselte Daten:" + deryptionData);
}
}
AbstractEncryption.java
package common;
import main.Main;
/**
*Klasse, die sowohl für die Verschlüsselung als auch für die Entschlüsselung verantwortlich ist
* @author nobu
*
*/
public abstract class AbstractEncryption {
/**
*Führen Sie die Ver- und Entschlüsselung durch
* @param secretData geheime Daten
* @param key privater Schlüssel
*/
public String execEncryption(String secretData, int key[]) {
String left = secretData.substring(0, secretData.length() / 2);
String right = secretData.substring(secretData.length() / 2, secretData.length());
//Zeichenfolgendaten links, Variable zum Speichern verschlüsselter Daten
byte leftArray[][];
//Die Zeichen auf der linken Seite betrachten den Fall, in dem die Anzahl der Zeichen in den geheimen Daten gerade oder ungerade ist.
if (secretData.length() % 2 == 0) {
leftArray = new byte[Main.ROUND_EXEC_TIME + 1][left.length()];
} else {
leftArray = new byte[Main.ROUND_EXEC_TIME + 1][left.length() + 1];
}
//Variablen zum Speichern der Zeichenkettendaten auf der rechten Seite und verschlüsselter Daten
byte rightArray[][] = new byte[Main.ROUND_EXEC_TIME + 1][right.length()];
//Initialisierung des Eingabewerts
for (int i = 0; i < left.length(); i++) {
leftArray[0][i] = (byte) left.charAt(i);
}
for (int i = 0; i < right.length(); i++) {
rightArray[0][i] = (byte) right.charAt(i);
}
//Verschlüsselung,Entschlüsselung
for (int i = 0; i < Main.ROUND_EXEC_TIME; i++) {
for (int j = 0; j < right.length(); j++) {
rightArray[i + 1][j] = encryption(leftArray[i][j], rightArray[i][j], key, i);
leftArray[i + 1][j] = rightArray[i][j];
}
//In der letzten Runde werden links und rechts nicht ausgetauscht, sodass die bereits ausgetauschten Daten wiederhergestellt werden.
if (i == Main.ROUND_EXEC_TIME - 1) {
byte tmp[];
tmp = leftArray[i + 1];
leftArray[i + 1] = rightArray[i + 1];
rightArray[i + 1] = tmp;
}
}
String returnData = "";
for (int i = 0; i < right.length(); i++) {
returnData = returnData + String.valueOf((char) leftArray[Main.ROUND_EXEC_TIME][i]);
}
for (int i = 0; i < right.length(); i++) {
returnData = returnData + String.valueOf((char) rightArray[Main.ROUND_EXEC_TIME][i]);
}
return returnData;
}
/**
*Verschlüsselung
* @param left Daten links
* @param rechts Daten rechts
* @param key privater Schlüssel
* @param roundNumber
* @return Das Ergebnis der Verschlüsselung
*/
abstract protected byte encryption(byte left, byte right, int[] key, int roundNumber);
/**
*Die Rundungsfunktion verschiebt sich um den vom privaten Schlüssel angegebenen Wert nach rechts
* @param rechts richtig Daten
* @param key privater Schlüssel
* @Ergebnis der Rundenfunktion zurückgeben
*/
protected byte roundFunction(byte right, int key) {
return (byte) (right << key);
}
}
Encryption.java
package encryption;
import common.AbstractEncryption;
/**
*Verschlüsselungsklasse
* @author nobu
*
*/
public class Encryption extends AbstractEncryption {
@Override
protected byte encryption(byte left, byte right, int[] key, int roundNumber) {
return (byte) (left ^ roundFunction(right, key[roundNumber]));
}
}
Decryption.java
package encryption;
import common.AbstractEncryption;
import main.Main;
/**
*Entschlüsselungsklasse
* @author nobu
*
*/
public class Decryption extends AbstractEncryption {
@Override
protected byte encryption(byte left, byte right, int[] key, int roundNumber) {
return (byte) (left ^ roundFunction(right, key[Main.ROUND_EXEC_TIME - roundNumber - 1]));
}
}
Dies ist das Ergebnis der Verschlüsselung der Zeichenfolge "Testfall" und der Entschlüsselung der verschlüsselten Daten.
Verschlüsselte Daten: 8 he ᆪ i hee
Entschlüsselte Daten: Testfall
Einführung in die Kryptografietechnologie, 3. Ausgabe
Recommended Posts