SimpleDES 算法 java 實現

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章