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