DES, l'une des méthodes de cryptage à clé courantes, utilise une structure appelée réseau de fistule. En bref, il s'agit d'une méthode de chiffrement qui utilise une fonction appelée fonction ronde et une somme logique exclusive. Dans DES, il existe une règle selon laquelle le texte brut de l'entrée est de 64 bits et la longueur en bits de la clé est de 56 bits, mais cette fois, je voulais juste implémenter un réseau de fistule, de telles restrictions sont donc exclues.
[Référence] Explication de la structure de Feistel sur Wikipedia
Le code affiché ici est publié sur GitHub lié ci-dessous. feistelNetwork
Main.java
package main;
import common.AbstractEncryption;
import encryption.Decryption;
import encryption.Encryption;
public class Main {
//Nombre de tours
public static int ROUND_EXEC_TIME = 3;
//Clé privée utilisée dans la fonction ronde
//Puisque la fonction d'arrondi effectue une opération de décalage de bits, elle ne peut pas être chiffrée à moins qu'un nombre inférieur à 8 ne soit spécifié.
//Cette clé doit être gardée secrète pour éviter qu'elle ne soit piratée par un attaquant
private static int[] SECRET_KEY = {2, 3, 6};
public static void main(String[] args) {
//Données confidentielles
String secretData = "testcase";
AbstractEncryption encryption = new Encryption();
AbstractEncryption decryption = new Decryption();
//chiffrement
String encryptionData = encryption.execEncryption(secretData, SECRET_KEY);
//Décryptage
String deryptionData = decryption.execEncryption(encryptionData, SECRET_KEY);
System.out.println("Données cryptées:" + encryptionData);
System.out.println("Données décryptées:" + deryptionData);
}
}
AbstractEncryption.java
package common;
import main.Main;
/**
*Classe responsable à la fois du cryptage et du décryptage
* @author nobu
*
*/
public abstract class AbstractEncryption {
/**
*Effectuer le cryptage et le décryptage
* @param secretData données secrètes
* @clé privée clé param
*/
public String execEncryption(String secretData, int key[]) {
String left = secretData.substring(0, secretData.length() / 2);
String right = secretData.substring(secretData.length() / 2, secretData.length());
//Données de chaîne de caractères à gauche, variable pour stocker les données cryptées
byte leftArray[][];
//Les caractères de gauche considèrent le cas où le nombre de caractères dans les données secrètes est pair ou impair.
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 pour stocker les données de la chaîne de caractères sur le côté droit et les données cryptées
byte rightArray[][] = new byte[Main.ROUND_EXEC_TIME + 1][right.length()];
//Initialisation de la valeur d'entrée
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);
}
//chiffrement,Décryptage
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];
}
//Dans le dernier tour, la gauche et la droite ne sont pas échangées, les données déjà échangées sont donc restaurées.
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;
}
/**
*chiffrement
* @param left Data sur la gauche
* @param right Données à droite
* @clé privée clé param
* @param roundNumber
* @return Le résultat du chiffrement
*/
abstract protected byte encryption(byte left, byte right, int[] key, int roundNumber);
/**
*Fonction Round, décale vers la droite de la valeur spécifiée par la clé privée
* @param right right data
* @clé privée clé param
* @retourne le résultat de la fonction Round
*/
protected byte roundFunction(byte right, int key) {
return (byte) (right << key);
}
}
Encryption.java
package encryption;
import common.AbstractEncryption;
/**
*Classe de cryptage
* @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;
/**
*Classe de décryptage
* @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]));
}
}
C'est le résultat du cryptage de la chaîne de caractères «testcase» et du décryptage des données cryptées.
Données cryptées: 8 ᄀ ᆪ i hee
Données décryptées: testcase
Introduction à la technologie cryptographique 3e édition
Recommended Posts