SimpleDES是为讲解DES算法而简化了的算法。
算法文本说明请在正面链接下载
http://homepage.smc.edu/morgan_david/vpn/C-SDES.pdf
算法来自参考资料1,为方便学习,我加了注释说明。
将文件中的截图也上传上来,方便查看。
图1(Figure C.1 Simplified DES Scheme):
图2(Figure C.2 Key Generation for Simplified DES):
图3(Figure C.3 Simplified DES Encryption Detail):
SimpleDESTest.java 代码如下:
import java.io.IOException;
import java.util.Arrays;
public class SimpleDESTest {
// two keys K1 and K2
static int K1 = 0;
static int K2 = 0;
/* some parameters */
static int P10[] = new int[] { 3, 5, 2, 7, 4, 10, 1, 9, 8, 6 };
static int P8[] = new int[] { 6, 3, 7, 4, 8, 5, 10, 9 };
static int P4[] = new int[] { 2, 4, 3, 1 };
static int IP[] = new int[] { 2, 6, 3, 1, 4, 8, 5, 7 };
static int IPI[] = new int[] { 4, 1, 3, 5, 7, 2, 8, 6 };
static int EP[] = new int[] { 4, 1, 2, 3, 2, 3, 4, 1 };
static int S0[][] = { { 1, 0, 3, 2 }, { 3, 2, 1, 0 }, { 0, 2, 1, 3 },
{ 3, 1, 3, 2 }, };
static int S1[][] = { { 0, 1, 2, 3 }, { 2, 0, 1, 3 }, { 3, 0, 1, 0 },
{ 2, 1, 0, 3 }, };
// 根据数组交换
static int Permute(int num, int p[], int pmax) {
int result = 0;
System.out.println(" start Permute");
System.out.println(" num:" + Integer.toString(num, 2));
System.out.println(" p:" + Arrays.toString(p));
System.out.println(" pmax:" + Integer.toString(pmax, 2));
for (int i = 0; i < p.length; i++) {
result <<= 1;
// System.out.println(" " + i + ":result <<= 1," +
// Integer.toString(result, 2) + "," + Integer.toString(p[i], 2));
result |= (num >> (pmax - p[i])) & 1;
// System.out.println(" result |= (num >> (pmax - p[i])) & 1," +
// Integer.toString(result, 2));
}
System.out.println(" result:" + Integer.toString(result, 2));
System.out.println(" end Permute");
return result;
}
// 生成k1,k2
static void SDES(String Key) {
int K = Integer.parseInt(Key, 2);
System.out.println("start generate K1");
K = Permute(K, P10, 10);
System.out.println(" K:" + Integer.toString(K, 2));
int th = 0, tl = 0;
th = (K >> 5) & 0x1f;// 取Key的高5位
tl = K & 0x1f; // 取Key的低5位
System.out.println(" K top 5:" + Integer.toString(th, 2));
System.out.println(" K low 5:" + Integer.toString(tl, 2));
// LS-1
th = ((th & 0xf) << 1) | ((th & 0x10) >> 4);// 循环左移一位
tl = ((tl & 0xf) << 1) | ((tl & 0x10) >> 4);// 循环左移一位
System.out.println(" K top 5 LS-1:" + Integer.toString(th, 2));
System.out.println(" K low 5 LS-1:" + Integer.toString(tl, 2));
K1 = Permute((th << 5) | tl, P8, 10); // 生成K1
System.out.println(" K1:" + Integer.toString(K1, 2));
System.out.println("end generate K1");
System.out.println("start generate K2");
// LS-2
System.out.println(" K top 5:" + Integer.toString(th, 2));
System.out.println(" K low 5:" + Integer.toString(tl, 2));
th = ((th & 0x07) << 2) | ((th & 0x18) >> 3);// 循环左移二位
tl = ((tl & 0x07) << 2) | ((tl & 0x18) >> 3);// 循环左移二位
System.out.println(" K top 5 LS-2:" + Integer.toString(th, 2));
System.out.println(" K low 5 LS-2:" + Integer.toString(tl, 2));
K2 = Permute((th << 5) | tl, P8, 10); // 生成K2
System.out.println(" K2:" + Integer.toString(K2, 2));
System.out.println("end generate K2");
}
// f函数
static int F(int R, int K) {
System.out.println(" start F");
System.out.println(" R:" + Integer.toString(R, 2));
System.out.println(" K:" + Integer.toString(K, 2));
int t = Permute(R, EP, 4) ^ K;
System.out.println(" Permute(R, EP, 4) ^ K:" + Integer.toString(t, 2));
int t0 = (t >> 4) & 0xf;
int t1 = t & 0xf;
System.out.println(" F top 4:" + Integer.toString(t0, 2));
System.out.println(" F low 4:" + Integer.toString(t1, 2));
int x1 = ((t0 & 0x8) >> 2) | (t0 & 1);
int y1 = (t0 >> 1) & 0x3;
int x2 = ((t1 & 0x8) >> 2) | (t1 & 1);
int y2 = (t1 >> 1) & 0x3;
t0 = S0[x1][y1];
t1 = S1[x2][y2];
System.out.println(" F top 4 S0[" + Integer.toString(x1, 2) + "]["
+ Integer.toString(y1, 2) + "]:" + Integer.toString(t0, 2));
System.out.println(" F low 4 S1[" + Integer.toString(x2, 2) + "]["
+ Integer.toString(y2, 2) + "]:" + Integer.toString(t1, 2));
t = Permute((t0 << 2) | t1, P4, 4);
System.out.println(" Permute((t0 << 2) | t1, P4, 4):"
+ Integer.toString(t, 2));
System.out.println(" end F");
return t;
}
// fk函数
static int fk(int input, int k) {
System.out.println(" input:" + Integer.toString(input, 2));
System.out.println(" k:" + Integer.toString(k, 2));
int l = (input >> 4) & 0xf;
int r = input & 0xf;
System.out.println(" fk top 4:" + Integer.toString(l, 2));
System.out.println(" fk low 4:" + Integer.toString(r, 2));
return ((l ^ F(r, k)) << 4) | r;
}
// switch function
static int SW(int x) {
return ((x & 0xf) << 4) | ((x >> 4) & 0xf);
}
// 加密
static String encrypt(String input) {
int m = Integer.parseInt(input, 2);
m = Permute(m, IP, 8);
System.out.println(" Permute(m, IP, 8)=" + Integer.toString(m, 2));
m = fk(m, K1);
System.out.println(" fk(m, K1)=" + Integer.toString(m, 2));
m = SW(m);
System.out.println(" SW(m)=" + Integer.toString(m, 2));
m = fk(m, K2);
System.out.println(" fk(m, K2)=" + Integer.toString(m, 2));
m = Permute(m, IPI, 8);
System.out.println(" Permute(m, IPI, 8)=" + Integer.toString(m, 2));
return Integer.toString(m, 2);
}
// 解密
static String decrypt(String input) {
int m = Integer.parseInt(input, 2);
System.out.println("start IP");
m = Permute(m, IP, 8);
System.out.println(" Permute(m, IP, 8)=" + Integer.toString(m, 2));
System.out.println("end IP");
System.out.println("start fk K2");
m = fk(m, K2);
System.out.println(" fk(m, K2)=" + Integer.toString(m, 2));
System.out.println("end fk K2");
System.out.println("start SW");
m = SW(m);
System.out.println(" SW(m)=" + Integer.toString(m, 2));
System.out.println("end SW");
System.out.println("start fk K1");
m = fk(m, K1);
System.out.println(" fk(m, K1)=" + Integer.toString(m, 2));
System.out.println("end fk K1");
System.out.println("start IIP");
m = Permute(m, IPI, 8);
System.out.println(" Permute(m, IPI, 8)=" + Integer.toString(m, 2));
System.out.println("end IIP");
System.out.println("end decrypt");
return Integer.toString(m, 2);
}
public static void main(String[] args) throws IOException {
String plaintext, ciphertext, key;
java.util.Scanner scan = new java.util.Scanner(System.in);
String command = "1:加密(encrypt),2:解密(decrypt),3:退出(exit),请输入一个数字来选择:";
String inputPlainText = "请输入明文(8 bit plaintext):";
String inputCipherText = "请输入密文(8 bit ciphertext):";
String inputKey = "请输入密钥(10 bit key):";
System.out.println(command);
int mode = scan.nextInt();
while (true) {
if (mode == 1) {
System.out.println(inputPlainText);
plaintext = scan.next();
System.out.println(inputKey);
key = scan.next();
SDES(key);
ciphertext = encrypt(plaintext);
// 如果密文不足8位,补足8位
if (ciphertext.length() < 8) {
for (int i = 0; i < 8 - ciphertext.length(); i++)
ciphertext = "0" + ciphertext;
}
System.out.println("加密后的密文(8 bit ciphertext)为:" + ciphertext);
} else if (mode == 2) {
System.out.println(inputCipherText);
ciphertext = scan.next();
System.out.println(inputKey);
key = scan.next();
SDES(key);
plaintext = decrypt(ciphertext);
if (plaintext.length() < 8) {
for (int i = 0; i < 8 - plaintext.length(); i++)
plaintext = "0" + plaintext;
}
System.out.println("解密后的明文(8 bit plaintext)为:" + plaintext);
} else if (mode == 3)
break;
System.out.println(command);
mode = scan.nextInt();
}
}
}
对密文10100010,密钥0111111101解密的过程如下:
1:加密(encrypt),2:解密(decrypt),3:退出(exit),请输入一个数字来选择:
2
请输入密文(8 bit ciphertext):
10100010
请输入密钥(10 bit key):
0111111101
start generate K1
start Permute
num:111111101
p:[3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
pmax:1010
result:1111110011
end Permute
K:1111110011
K top 5:11111
K low 5:10011
K top 5 LS-1:11111
K low 5 LS-1:111
start Permute
num:1111100111
p:[6, 3, 7, 4, 8, 5, 10, 9]
pmax:1010
result:1011111
end Permute
K1:1011111
end generate K1
start generate K2
K top 5:11111
K low 5:111
K top 5 LS-2:11111
K low 5 LS-2:11100
start Permute
num:1111111100
p:[6, 3, 7, 4, 8, 5, 10, 9]
pmax:1010
result:11111100
end Permute
K2:11111100
end generate K2
start IP
start Permute
num:10100010
p:[2, 6, 3, 1, 4, 8, 5, 7]
pmax:1000
result:110001
end Permute
Permute(m, IP, 8)=110001
end IP
start fk K2
input:110001
k:11111100
fk top 4:11
fk low 4:1
start F
R:1
K:11111100
start Permute
num:1
p:[4, 1, 2, 3, 2, 3, 4, 1]
pmax:100
result:10000010
end Permute
Permute(R, EP, 4) ^ K:1111110
F top 4:111
F low 4:1110
F top 4 S0[1][11]:0
F low 4 S1[10][11]:0
start Permute
num:0
p:[2, 4, 3, 1]
pmax:100
result:0
end Permute
Permute((t0 << 2) | t1, P4, 4):0
end F
fk(m, K2)=110001
end fk K2
start SW
SW(m)=10011
end SW
start fk K1
input:10011
k:1011111
fk top 4:1
fk low 4:11
start F
R:11
K:1011111
start Permute
num:11
p:[4, 1, 2, 3, 2, 3, 4, 1]
pmax:100
result:10010110
end Permute
Permute(R, EP, 4) ^ K:11001001
F top 4:1100
F low 4:1001
F top 4 S0[10][10]:1
F low 4 S1[11][0]:10
start Permute
num:110
p:[2, 4, 3, 1]
pmax:100
result:1010
end Permute
Permute((t0 << 2) | t1, P4, 4):1010
end F
fk(m, K1)=10110011
end fk K1
start IIP
start Permute
num:10110011
p:[4, 1, 3, 5, 7, 2, 8, 6]
pmax:1000
result:11101010
end Permute
Permute(m, IPI, 8)=11101010
end IIP
end decrypt
解密后的明文(8 bit plaintext)为:11101010
1:加密(encrypt),2:解密(decrypt),3:退出(exit),请输入一个数字来选择:
对明文11101010,密钥011111101的加密过程如下:
1:加密(encrypt),2:解密(decrypt),3:退出(exit),请输入一个数字来选择:
1
请输入明文(8 bit plaintext):
11101010
请输入密钥(10 bit key):
0111111101
start generate K1
start Permute
num:111111101
p:[3, 5, 2, 7, 4, 10, 1, 9, 8, 6]
pmax:1010
result:1111110011
end Permute
K:1111110011
K top 5:11111
K low 5:10011
K top 5 LS-1:11111
K low 5 LS-1:111
start Permute
num:1111100111
p:[6, 3, 7, 4, 8, 5, 10, 9]
pmax:1010
result:1011111
end Permute
K1:1011111
end generate K1
start generate K2
K top 5:11111
K low 5:111
K top 5 LS-2:11111
K low 5 LS-2:11100
start Permute
num:1111111100
p:[6, 3, 7, 4, 8, 5, 10, 9]
pmax:1010
result:11111100
end Permute
K2:11111100
end generate K2
start Permute
num:11101010
p:[2, 6, 3, 1, 4, 8, 5, 7]
pmax:1000
result:10110011
end Permute
Permute(m, IP, 8)=10110011
input:10110011
k:1011111
fk top 4:1011
fk low 4:11
start F
R:11
K:1011111
start Permute
num:11
p:[4, 1, 2, 3, 2, 3, 4, 1]
pmax:100
result:10010110
end Permute
Permute(R, EP, 4) ^ K:11001001
F top 4:1100
F low 4:1001
F top 4 S0[10][10]:1
F low 4 S1[11][0]:10
start Permute
num:110
p:[2, 4, 3, 1]
pmax:100
result:1010
end Permute
Permute((t0 << 2) | t1, P4, 4):1010
end F
fk(m, K1)=10011
SW(m)=110001
input:110001
k:11111100
fk top 4:11
fk low 4:1
start F
R:1
K:11111100
start Permute
num:1
p:[4, 1, 2, 3, 2, 3, 4, 1]
pmax:100
result:10000010
end Permute
Permute(R, EP, 4) ^ K:1111110
F top 4:111
F low 4:1110
F top 4 S0[1][11]:0
F low 4 S1[10][11]:0
start Permute
num:0
p:[2, 4, 3, 1]
pmax:100
result:0
end Permute
Permute((t0 << 2) | t1, P4, 4):0
end F
fk(m, K2)=110001
start Permute
num:110001
p:[4, 1, 3, 5, 7, 2, 8, 6]
pmax:1000
result:10100010
end Permute
Permute(m, IPI, 8)=10100010
加密后的密文(8 bit ciphertext)为:10100010
1:加密(encrypt),2:解密(decrypt),3:退出(exit),请输入一个数字来选择:
参考资料
1.simple-des算法的java实现.http://blog.csdn.net/jason314/article/details/5425248
2.《Cryptography and Network Security Principles and Practice》.appendix C Simplified DES.http://homepage.smc.edu/morgan_david/vpn/C-SDES.pdf