DES, one of the common key cryptosystems, uses a structure called a fistula network. Briefly, it is an encryption method that uses a function called a round function and exclusive OR. In DES, there are rules such as 64 bits for plaintext of input and 56 bits for key bit length, but this time I just wanted to implement a fistula network, so such restrictions are excluded.
[Reference] Explanation of Feistel structure in Wikipedia
The code posted here is posted on GitHub linked below. feistelNetwork
Main.java
package main;
import common.AbstractEncryption;
import encryption.Decryption;
import encryption.Encryption;
public class Main {
//Number of rounds
public static int ROUND_EXEC_TIME = 3;
//Private key used in round function
//Since the round function performs bit shift operation, it cannot be encrypted unless a number smaller than 8 is specified.
//This key must be kept secret to prevent it from being cracked by an attacker
private static int[] SECRET_KEY = {2, 3, 6};
public static void main(String[] args) {
//Confidential data
String secretData = "testcase";
AbstractEncryption encryption = new Encryption();
AbstractEncryption decryption = new Decryption();
//encryption
String encryptionData = encryption.execEncryption(secretData, SECRET_KEY);
//Decryption
String deryptionData = decryption.execEncryption(encryptionData, SECRET_KEY);
System.out.println("Encrypted data:" + encryptionData);
System.out.println("Decrypted data:" + deryptionData);
}
}
AbstractEncryption.java
package common;
import main.Main;
/**
*A class responsible for both encryption and decryption
* @author nobu
*
*/
public abstract class AbstractEncryption {
/**
*Perform encryption and decryption
* @param secretData secret data
* @param key private key
*/
public String execEncryption(String secretData, int key[]) {
String left = secretData.substring(0, secretData.length() / 2);
String right = secretData.substring(secretData.length() / 2, secretData.length());
//Character string data on the left side, variable for storing encrypted data
byte leftArray[][];
//The characters on the left consider the case where the number of characters in the secret data is even or odd.
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];
}
//Variables for storing character string data and encrypted data on the right side
byte rightArray[][] = new byte[Main.ROUND_EXEC_TIME + 1][right.length()];
//Initialization of input value
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);
}
//encryption,Decryption
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 the final round, the left and right are not exchanged, so the already exchanged data is restored.
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;
}
/**
*encryption
* @param left Data on the left
* @param right data on the right
* @param key private key
* @param roundNumber
* @return encryption result
*/
abstract protected byte encryption(byte left, byte right, int[] key, int roundNumber);
/**
*Round function, shifts right by the value specified by the private key
* @param right right data
* @param key private key
* @return Round function result
*/
protected byte roundFunction(byte right, int key) {
return (byte) (right << key);
}
}
Encryption.java
package encryption;
import common.AbstractEncryption;
/**
*Encryption class
* @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;
/**
*Decryption class
* @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]));
}
}
This is the result of encrypting the character string "testcase" and decrypting the encrypted data.
Encrypted data: 8 ᄀ ᆪ i hee
Decrypted data: testcase
Introduction to Cryptography 3rd Edition
Recommended Posts