Java实现S-DES加密算法

S-DES

为了更好的理解DES算法,美国圣塔克拉拉大学的Edward Schaefer教授于1996年开发了Simplified DES方案,简称S-DES方案。它是一个供教学二非安全的加密算法,它与DES的特性和结构类似,但参数小,明文分组为8位,主密钥分组为10位,采用两轮迭代。

S-DES加密原理

加密原理图
1.初始置换IP:将8位的明文按照顺序(26314857)进行位置变化,置换后分为左4位L0和右4位R0.
2.第1轮运算,R0一方面直接输出作为下一轮的L1,另一方面作为f函数的输入与8位的子密钥K1参与函数运算,运算结果与L0异或,结果作为下一轮的R1.
3.第2轮运算,R1一方面直接输出作为下一轮R2,另一方面作为f函数的输入与8位的子密钥K2参与函数运算,运算结果与L1异或,结果作为下一轮的L2.
4.逆置换IP-1.在S-DES的整个加密过程中,包含两个重要的组成部分,一个是子密码生成过程,一个是f函数结构

子密钥的生成:

在这里插入图片描述
1.主密钥K进行P10置换(3、5、2、7、4、10、1、9、8、6).
2.分成左5位和右5位,再分别进行LS-1操作(左循环1位),其结果一方面作为下一轮的初始值,一方面进行P8置换(6、3、7、4、8、5、10、9),得到K1(P8相当于将10位截取成8位)。
3.再分别左循环2位,经过P8置换,得到K2.

f函数:

在这里插入图片描述
1.E/P扩展及置换:将4位R0或R1扩展为8位。
2.扩展后的8位与密钥K1或K2异或,输出8位
3.左边4位作为S1盒输入,右边作为S2盒输入。
4.在S1和S2中,第1位与第4位结合形成2位代表S盒的行号,第2位与第3位结合形成2位代表S盒的列号,得到S盒的输出。S-DES盒在下面有。
5.进行P4置换,得到f函数的输出

S-DES的S盒:

S1 00 01 10 11 S2 00 01 10 11
00 01 00 11 10 00 00 01 10 11
01 11 10 01 00 01 10 00 01 11
10 00 10 01 11 10 11 10 01 00
11 11 01 00 10 11 10 01 00 11

代码:

import java.util.Scanner;

//置换还有S盒的设置
public class S_DES {
public static String key1;
public static String key2;
public static int[] IP = new int[] { 2, 6, 3, 1, 4, 8, 5, 7 };
public static int[] EP = new int[] { 4, 1, 2, 3, 2, 3, 4, 1 };
public static int[] P10 = new int[] { 3, 5, 2, 7, 4, 10, 1, 9, 8, 6 };
public static int[] P8 = new int[] { 6, 3, 7, 4, 8, 5, 10, 9 };
public static int[] P4 = new int[] { 2, 4, 3, 1 };
public static int[] IP_1 = new int[] { 4, 1, 3, 5, 7, 2, 8, 6 };
public static String[][] S1_box = new String[][] {
		{ "01", "00", "11", "10" }, { "11", "10", "01", "00" },
		{ "00", "10", "01", "11" }, { "11", "01", "00", "10" } };
public static String[][] S2_box = new String[][] {
		{ "00", "01", "10", "11" }, { "10", "00", "01", "11" },
		{ "11", "10", "01", "00" }, { "10", "01", "00", "11" } };
public static String substitue(String str, int[] P) { //进行置换操作    
	StringBuilder sb = new StringBuilder();
	for (int i = 0; i < P.length; i++) {
		sb.append(str.charAt((P[i]) - 1));
	}
	return new String(sb);
}

public static String xor(String str, String key) { //进行异或操作
	StringBuilder sb = new StringBuilder();
	for (int i = 0; i < str.length(); i++) {
		if (str.charAt(i) == key.charAt(i)) {
			sb.append("0");
		} else {
			sb.append("1");
		}
	}
	return new String(sb);
}

public static String searchSbox(String str, int n) { //S盒的查找
	StringBuilder sb = new StringBuilder();
	sb.append(str.charAt(0));
	sb.append(str.charAt(3));
	String ret = new String(sb);
	StringBuilder sb1 = new StringBuilder();
	sb1.append(str.charAt(1));
	sb1.append(str.charAt(2));
	String ret1 = new String(sb1);
	String retu = new String();
	if (n == 1) {
		retu = S1_box[Integer.parseInt(ret, 2)][Integer.parseInt(ret1, 2)];
	} else {
		retu = S2_box[Integer.parseInt(ret, 2)][Integer.parseInt(ret1, 2)];
	}
	return retu;
}

public static void getkey() { //获得key1和key2
	System.out.println("-----请输入主密钥(10位)------");
	Scanner sc = new Scanner(System.in);
	String mainkey = sc.nextLine();
	mainkey = substitue(mainkey, P10);
	String Ls11 = mainkey.substring(0, 5);
	Ls11 = move(Ls11, 1);//移位后
	String Ls12 = mainkey.substring(5, 10);
	Ls12 = move(Ls12, 1);//移位后
	key1 = Ls11 + Ls12;
	key1 = substitue(key1, P8);
	System.out.println("key1= " + key1);
	String Ls21 = move(Ls11, 2);
	String Ls22 = move(Ls12, 2);
	key2 = Ls21 + Ls22;
	key2 = substitue(key2, P8);
	System.out.println("key2= " + key2);
}

public static String move(String str, int n) { //进行移位操作,只能1位或者2位
	char[] ch = str.toCharArray();
	char[] copy_ch = new char[5];
	for (int i = 0; i < ch.length; i++) {
		int a = ((i - n) % ch.length);
		if (a < 0) {
			if (n == 1) {
				copy_ch[ch.length - 1] = ch[i];
			}
			if (n == 2) {
				if (i == 0) {
					copy_ch[ch.length - 2] = ch[i];
				} else {
					copy_ch[ch.length - 1] = ch[i];
				}

			}
		} else {
			copy_ch[a] = ch[i];
		}
	}
	return new String(copy_ch);
}

public static void encrypt() { //加密主体
	System.out.println("-----请输入要加密的信息(8位)------");
	Scanner sc = new Scanner(System.in);
	String plaintext = sc.nextLine();
	plaintext = substitue(plaintext, IP);
	String L0 = plaintext.substring(0, 4);
	String R0 = plaintext.substring(4, 8);
	String R0E = substitue(R0, EP);
	R0E = xor(R0E, key1);
	String S1 = R0E.substring(0, 4);
	String S2 = R0E.substring(4, 8);
	S1 = searchSbox(S1, 1);
	S2 = searchSbox(S2, 2);
	String SS = S1 + S2;
	String f1 = substitue(SS, P4);
	String L1 = R0;
	String R1 = xor(f1, L0);
	//这里求出L1,R1
	//-----------------第二轮-------------
	String R11 = substitue(R1, EP);
	R11 = xor(R11, key2);
	S1 = R11.substring(0, 4);
	S2 = R11.substring(4, 8);
	S1 = searchSbox(S1, 1);
	S2 = searchSbox(S2, 2);
	SS = S1 + S2;
	String f2 = substitue(SS, P4);
	String L2 = xor(f2, L1);
	String R2 = R1;
	//这里求出L2,R2
	String ciphertext = L2 + R2;
	ciphertext = substitue(ciphertext, IP_1);
	System.out.println("密文: " + ciphertext);
}

public static void main(String[] args) {
	getkey();
	encrypt();
 }
 }

结果测试:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lb121zc/article/details/83243163