深入理解并实现DES算法

一、DES简介

  • DES算法属于分组加密算法
  • 信息按照固定长度进行分组,分组长度为64位
  • 混淆和扩散是它采用的两个最重要的安全特性
    • 混淆是指通过密码算法使明文和密文以及密钥的关系非常复杂,无法从数学上描述或者统计。
    • 扩散是指明文和密钥中的每一位信息的变动,都会影响到密文中许多位信息的变动,从而隐藏统计上的特性,增加密码的安全。

需要注意的地方是掌握DES算法的16轮加、解密流程以及子密钥的产生流程。

二、DES实现大纲

在我的另一篇博客《加密算法之对称加密–DES》已经提到过DES算法的大致过程,整个流程如下图:
这里写图片描述
为了深入理解整个流程,我们将细化讲解DES算法里十六轮迭代变化中的子密钥生成以及F函数

三、DES算法之子密钥生成

1. 子密钥生成流程

流程图

这里写图片描述

子密钥置换选择1(把64位的密钥变为56位长)

假设原密钥为 K s = k 1 , k 2 , k 3 , . . . . . . , k 64 K_s= k_1,k_2,k_3,......,k_{64} Ks=k1,k2,k3,......,k64

DES算法的实际密钥长度为56,因为64位原密钥每8位的最后一位,即第8,16,24,32,40,48,56,64位为校验位。通过如下的置换规则,将实际的 56 56 56为位密钥选择出来并置乱:
57 49 41 33 25 17 9 1 58 50 42 34 26 18 10 2 59 51 43 35 27 19 11 3 60 52 44 36 63 55 47 39 31 23 15 7 62 54 46 38 30 22 14 6 61 53 45 37 29 21 13 5 28 20 12 4 \begin{array}{lllllll} 57 & 49 & 41 & 33 & 25 & 17 & 9 \\ 1 & 58 & 50 & 42 & 34 & 26 & 18 \\ 10 & 2 & 59 & 51 & 43 & 35 & 27 \\ 19 & 11 & 3 & 60 & 52 & 44 & 36 \\ 63 & 55 & 47 & 39 & 31 & 23 & 15 \\ 7 & 62 & 54 & 46 & 38 & 30 & 22 \\ 14 & 6 & 61 & 53 & 45 & 37 & 29 \\ 21 & 13 & 5 & 28 & 20 & 12 & 4 \end{array} 57110196371421495821155626134150593475461533425160394653282534435231384520172635442330371291827361522294

因此通过置换选择1之后,56位密钥为 K s ′ = k 1 , k 2 , k 3 . . . . . . k 56 K_{s' }= k_1,k_2,k_3......k_{56} Ks=k1,k2,k3......k56,其中 k 1 = K s [ 57 ] , k 2 = K s [ 49 ] , k 3 = K s [ 41 ] , . . . . . . k 56 = K s [ 4 ] k_1 = K_{s[57]}, k_2 = K_{s[49]},k_3 = K_{s[41]},......k_{56} = K_{s[4]} k1=Ks[57],k2=Ks[49],k3=Ks[41],......k56=Ks[4]

子密钥迭代变换

实际密钥 K s ′ = k 1 , k 2 , k 3 . . . . . . k 56 K_{s' }= k_1,k_2,k_3......k_{56} Ks=k1,k2,k3......k56

(1)分组:将56位实际密钥分为Ci和Di两组

  • C i = k 1 , k 2 , . . . . . . , k 28 C_i = k_1,k_2,......,k_{28} Ci=k1,k2,......,k28
  • D i = k 29 , k 30 , . . . . . . k 56 D_i = k_{29},k_{30},......k_{56} Di=k29,k30,......k56

(2)循环移位(左移)

  • 移位判断表:
    1 1 9 1 2 1 10 2 3 2 11 2 4 2 12 2 5 2 13 2 6 2 14 2 7 2 15 2 8 2 16 1 \begin{array}{llll} 1 & 1 & 9 & 1 \\ 2 & 1 & 10 & 2 \\ 3 & 2 & 11 & 2 \\ 4 & 2 & 12 & 2 \\ 5 & 2 & 13 & 2 \\ 6 & 2 & 14 & 2 \\ 7 & 2 & 15 & 2 \\ 8 & 2 & 16 & 1 \end{array} 123456781122222291011121314151612222221
    第一列和第三列代表迭代次数,第二列和第四列代表对应的循环左移位数。
  • 第1,2,9,16轮迭代时循环左移一位,其余循环左移两位
  • 最终得到:
    • 循环左移一位: C i ′ = k 2 , k 3 , . . . . . . k 28 , k 1 ; D i ′ = K 30 , k 31 , . . . . . . k 56 , k 29 C_{i'}=k_2,k_3,......k_{28},k_1;D_{i'}=K_{30},k_{31},......k_{56},k_{29} Ci=k2,k3,......k28,k1Di=K30,k31,......k56,k29
    • 循环左移两位: C i ′ = k 3 , k 4 , . . . . . . k 1 , k 2 ; D i ′ = K 31 , k 32 , . . . . . . k 29 , k 30 C_{i'}=k_3,k_4,......k_1,k_2;D_{i'}=K_{31},k_{32},......k_{29},k_{30} Ci=k3,k4,......k1,k2Di=K31,k32,......k29,k30

(3) 选择置换2
将第(2)步得到的 C i ′ C_{i'} Ci以及 D i ′ D_{i'} Di拼接起来形成56位密钥 K s ′ ′ = [ C i ′ , D i ′ ] K_{s''} = [C_{i'},D_{i'}] Ks=[Ci,Di],
然后进行选择置换2,置换列表如下:
14 17 11 24 1 5 3 28 15 6 21 10 23 19 12 4 26 8 16 7 27 20 13 2 41 52 31 37 47 55 30 40 51 45 33 48 44 49 39 56 34 53 46 42 50 36 29 32 \begin{array}{lllllll} 14 & 17 & 11 & 24 & 1 & 5 \\ 3 & 28 & 15 & 6 & 21 & 10 \\ 23 & 19 & 12 & 4 & 26 & 8 \\ 16 & 7 & 27 & 20 & 13 & 2 \\ 41 & 52 & 31 & 37 & 47 & 55 \\ 30 & 40 & 51 & 45 & 33 & 48 \\ 44 & 49 & 39 & 56 & 34 & 53 \\ 46 & 42 & 50 & 36 & 29 & 32 \end{array} 1432316413044461728197524049421115122731513950246420374556361212613473334295108255485332

最后得到每一轮迭代所用到的48位子密钥 k i = k 1 , k 2 , k 3 , . . . . . . , k 48 k_i = k_1,k_2,k_3,......,k_{48} ki=k1,k2,k3,......,k48,其中 k 1 = K s ′ ′ [ 14 ] , k 2 = K s ′ ′ [ 17 ] , . . . . . . k 4 8 = K s ′ ′ [ 32 ] k_1 = K_{s''[14]}, k_2 = K_{s''[17]},......k_48 = K_{s''[32]} k1=Ks[14],k2=Ks[17],......k48=Ks[32].

四、DES算法之F函数变换

1. 圈变换

DES算法第i轮圈变换流程如下图:
这里写图片描述
根据此图可以得到迭代公式:

{ L i = R i − 1 R i = L i − 1 ⨁ f ( R i − 1 , K i ) , i = 1 , 2 , , , , 16 \left\{\begin{matrix} L_i=R_{i-1}\\R_i=L_{i-1}\bigoplus f(R_{i-1},K_i),i=1,2,,,,16 \end{matrix}\right. {Li=Ri1Ri=Li1f(Ri1,Ki),i=1,2,,,,16

并且可以很清晰的看到每一轮迭代所进行的操作,接下来将详细讲一下F函数中的操作

2. F函数

F函数梗概

这里写图片描述

E扩展置换
  • 将输入的32比特 R i R_i Ri每4比特为一组,共分为8块;
  • 分别将第 m − 1 m-1 m1块的最右比特和第 m + 1 m+1 m+1块的最左比特添到第 m m m块的左边和右边,形成输出的第 m m m 6 6 6比特块.
  • 形如:
    这里写图片描述
  • 理解:将1-32位看成一个环,因此第1位前是第32位,第4位后是第5位…
异或加密
  • 将前一步得到的 48 48 48位经过扩展序列与每一轮的密钥 k i k_i ki进行按位异或
S盒变换
  • 目的:将 48 48 48位序列压缩为$32v位序列

  • 过程详解:

    • 6 6 6位输入记为 B 1 , B 2 , B 3 , B 4 , B 5 , B 6 B1,B2,B3,B4,B5,B6 B1B2B3B4B5B6
    • B 1 B 6 B1B6 B1B6作为 S S S盒的行号, B 2 B 3 B 4 B 5 B2B3B4B5 B2B3B4B5作为 S S S盒的列号
  • S S S盒内容
    这里写图片描述

  • 举例
    这里写图片描述

P置换

经过 S S S盒变换的序列最后进行P置换,方式类似于之前的置换方式。
这里写图片描述

五、Java编程实现

public class DES_Key {
	
	public static void main(String[] args) {
		//Scanner input = new Scanner(System.in);
//		System.out.println("请输入十六进制明文:");
//		String plaintxt = input.next();
//		Integer tmpInt = Integer.valueOf(plaintxt,16);
//		String binary_plain = Integer.toBinaryString(tmpInt);
//		System.out.println(binary_plain);
//		System.out.println("请输入十六进制明文密钥:");
//		String Key = input.next();
		String Key = "1234567890ABCDFE";
		String binary_Key = hexString2binaryString(Key);
		System.out.print("binary_Key:");
		//0001 0010 0011 0100 0101 0110 0111 1000 1001 0000 1010 1011 1100 1101 1111 1110
		System.out.println(binary_Key);
		ArrayList<char[]> resultKi = new ArrayList<char[]>();//存放16个Ki
		GenerateKey(binary_Key,resultKi);
		
		Iterator<char[]> it = resultKi.iterator();
		int KiIndex = 0;
		while(it.hasNext()){
			char []temp = (char[]) it.next();
			System.out.print("第"+(KiIndex+1)+"轮密钥:");
			System.out.println(temp);
			KiIndex++;
		}
		
		String Plain = "1111111111111110";
		String binary_Plain = hexString2binaryString(Plain);
		System.out.print("binary_Plain:");
		System.out.println(binary_Plain);
		
		char[] DESEncrypt = EncryptCircleTrans(binary_Plain, resultKi);
		System.out.print("DES加密结果:");
		System.out.println(DESEncrypt);
		
		char[] DESDecrypt = DecryptCircleTrans(ToString(DESEncrypt), resultKi);
		System.out.print("DES解密结果:");
		System.out.println(DESDecrypt);
			
	}
	
	//辅助函数:将char转为String
	public static String ToString(char[]a){
		String b = "";
		for(int i=0;i<a.length;i++){
			b += a[i];
		}
		return b;
	}
	
	//char数组转为int
		public static int[] trsnChar2Int(char[] CharArr){
			int [] resultArr = new int[CharArr.length];
			for(int i=0;i<CharArr.length;i++){
				resultArr[i] = CharArr[i]-'0';
			}
			return resultArr;
		}
		
	//十六进制转2进制字符串
	public static String hexString2binaryString(String hexString)  
    {  
        if (hexString == null)  
            return null;  
        String bString = "", tmp;  
        for (int i = 0; i < hexString.length(); i++)  
        {  
            tmp = "0000"  
                    + Integer.toBinaryString(Integer.parseInt(hexString  
                            .substring(i, i + 1), 16));  
            bString += tmp.substring(tmp.length() - 4);  
        }  
        return bString;  
    }  

	//密钥选择置换PC_1 (64-56)
	public static char[] KeyPermutation1(String Key){
		char [] key = Key.toCharArray();//Get 64bits key array
		//System.out.println(key);
		char [] resultKey = new char[56];
		
		int PC_1[] = new int[]{57,49,41,33,25,17,9,1,58,50,42,34,26,18,
				10,2,59,51,43,35,27,19,11,3,60,52,44,36,
				63,55,47,39,31,23,15,7,62,54,46,38,30,22,
				14,6,61,53,45,37,29,21,13,5,28,20,12,4};
		
		for(int i=0;i<resultKey.length;i++){
			resultKey[i] = key[PC_1[i]-1];	
		}
		return resultKey;
		
	}
	//CD选择置换PC_2 (56-48)
	public static char[] KeyPermutation2(char[] CD){
		char [] cd = CD;//Get 56bits CD array
		//System.out.println(cd.length);
		char [] resultCd = new char[48];
		int PC_2[] = new int[]{14,17,11,24,1,5,3,28,15,6,21,10,
				23,19,12,4,26,8,16,7,27,20,13,2,
				41,52,31,37,47,55,30,40,51,45,33,48,
				44,49,39,56,34,53,46,42,50,36,29,32};
		
		for(int i=0;i<48;i++){
			resultCd[i] = cd[PC_2[i]-1];
		}
		return resultCd;
		
	}
	
	//循环生成密钥Ki
	public static char[] CircleGenKey(char[]C,char[]D,int flag){
		char [] Ci = C;
		char [] Di = D;

		if(flag == 0 || flag == 1 || flag == 8 || flag == 15 ){
			//循环左移1
			for(int i=0;i<28;i++){
				C[i] = Ci[(i+1)%28];
				D[i] = Di[(i+1)%28];
			}
			if(flag == 15)
				C[27] = '0';
		}
		else{//循环左移2
	        char temp0 = C[0];
	        char temp00 = D[0];
			for(int i=0;i<28;i++){	
				C[i] = C[(i+1)%28];
				D[i] = D[(i+1)%28];
			}
			C[27]=temp0;
			D[27]=temp00;
			
			char temp1=C[0];
			char temp11=D[0];
			for(int i=0;i<28;i++){
				C[i] = C[(i+1)%28];
				D[i] = D[(i+1)%28];		
			}
			C[27]=temp1;
			D[27]=temp11;
		}
		//System.out.println(C);
		//System.out.println(D);
		char [] ResultKey = new char[56];
		for(int i=0;i<28;i++){
			ResultKey[i]= C[i];
		}
		for(int j=28;j<56;j++){
			ResultKey[j]= D[j-28];
		}
		char[] ResultKi = KeyPermutation2(ResultKey);
		return ResultKi;//ki	
	}
	
	//生成密钥16轮Ki
	public static void GenerateKey(String Key,ArrayList<char[]> resultKi){
		
		char [] keySeed = KeyPermutation1(Key);//Get 56bits key that after OptPermutation PC_1
		char [] LeftC0 = new char[28];
		for(int i=0;i<LeftC0.length;i++){
			LeftC0[i] = keySeed[i];
		}
		char [] RightD0 = new char[28];
		for(int j=0;j<RightD0.length;j++){
			RightD0[j] = keySeed[j+28];
		}
		char [] LeftC = LeftC0;
		char [] RightD = RightD0;

		for(int i=0;i<16;i++){
			char[] temp = CircleGenKey(LeftC,RightD,i);
			resultKi.add(temp);
			//System.out.println(temp);
		}
	}

	//将原明文进行IP置换
	public static char[] InitialPermutation(char[] plaintxt)
	{
		char plain[] = plaintxt;
		int[] IP = new int[]{58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,
				62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8,
				57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,
				61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7};

		char[]result = new char[64];
		for(int i=0; i< plaintxt.length; i++){
			result[i]= plain[IP[i]-1];
		}
		return result ;
	}
	//IP 逆置换
	public static char[] ReverseInitialPermutation(char[]afterCircle)
	{
		char[] afterCircleTmp = afterCircle;
		char[] resultReverseIP = new char[64];
		int [] IPReverse = new int[]{
				40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
				38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
			    36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
				34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41,  9, 49, 17, 57, 25
		};
		
		for(int i=0;i<resultReverseIP.length;i++){
			resultReverseIP[i] = afterCircleTmp[IPReverse[i]-1];
		}
		
		return resultReverseIP;
	}
	
	//异或操作
	public static char[] XorAandB(char[]A,char[]B){
		char[]tmpA = A;
		char[]tmpB = B;
		int []OperateA = trsnChar2Int(tmpA);
		int []OperateB = trsnChar2Int(tmpB);
		if(OperateA.length != OperateB.length){
			return null;
		}
		
		char[] XorResult = new char[OperateA.length];
		
		for(int i=0;i<OperateA.length;i++){
			int temp = OperateA[i]^OperateB[i];
			XorResult[i] = (char) ('0'+temp);
		}
		return XorResult;
		
	}
	
	//E 扩展
	public static char[] FunctionExtension(char[] Ri){
		char[] tempRi = Ri;
		char[] resultRi = new char[48];
		int[] Extension = new int[]{32,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,
				12,13,14,15,16,17,16,17,18,19,20,21,20,21,22,23,24,25,
				24,25,26,27,28,29,28,29,30,31,32,1};
		for(int i=0;i<48;i++){
			resultRi[i] = tempRi[Extension[i]-1];
		}
		
		return resultRi;
	}

	//加密函数f 置换函数P
	public static char[] FunctionPermutation(char[] Sout ){
		char[] tempSout = Sout;
		char[] resultPout = new char[32];
		int [] Permutation = new int[]{16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,
				2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25};
		for(int i=0;i<32;i++){
			resultPout[i] = tempSout[Permutation[i]-1];
		}
		
		return resultPout;
	}
	
	//加密函数f S盒变换
	public static char[] SBoxTrans(char[] E_nor_Ki){
		int [][][] Sbox = new int[][][]{
			{{14,	 4,	13,	 1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7},
			 {0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8},
			 {4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0},
		     {15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13}},
			// S2 
		    {{15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10},
			 {3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5},
			 {0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15},
		     {13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9}},
			// S3 
		    {{10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8},
			 {13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1},
			 {13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7},
		     {1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12}},
			// S4 
		     {{7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15},
			  {13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9},
			  {10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4},
			  { 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14}},
			// S5 
		     {{2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9},
			  {14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6},
		      { 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14},
		      {11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3}},
			// S6 
		    {{12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11},
			 {10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8},
			 {9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6},
		     {4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13}},
			// S7 
		     {{4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1},
			  {13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6},
			  {1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2},
		      {6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12}},
			// S8 
		    {{13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7},
			 {1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2},
			 {7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8},
		     {2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11}}};
		    char outBox[] = new char[32];
			for(int i=0;i<8;i++){
				char[] temp6in = new char[6];
				
				for(int i1=0;i1<6;i1++){
					 temp6in[i1] = E_nor_Ki[i*6+i1];
				}
				//System.out.println(temp6in);
				int [] tem6in_int = trsnChar2Int(temp6in);
				int row = tem6in_int[0]*2+tem6in_int[5];
				int column = tem6in_int[1]*8+tem6in_int[2]*4+tem6in_int[3]*2+tem6in_int[4];
				int soutInt = Sbox[i][row][column];
				String HexSoutmp = Integer.toHexString(soutInt);
				
				char[] binarySoutChar = hexString2binaryString(HexSoutmp).toCharArray();
				
				int [] binarySoutInt = trsnChar2Int(binarySoutChar);
				
				for(int j=0;j<4;j++){
					outBox[i*4+j] = (char) ('0'+binarySoutInt[j]);
				}
			}
			return outBox;
	}
	
	//F函数
	public static char[] EcryptFunction(char[]Ri_1,char[]Ki){
		char []tmpRi_1 = Ri_1;
		char []tmpKi = Ki;
		char[] ExtensionR = FunctionExtension(tmpRi_1);//获得Ri经过E扩展后的数组32-48
		//Ri'与Ki异或操作
		char [] resultXorAandB = XorAandB(tmpKi,ExtensionR);

		char[]resultSBoxTrans = SBoxTrans(resultXorAandB);
		
		char[] FunctionResult = FunctionPermutation(resultSBoxTrans);
		
		return FunctionResult;
	}
	
	//DES 16轮加密圈变换
	public static char[] EncryptCircleTrans(String IPtxt,ArrayList<char[]> listKi){
		char[] IPtxt_tmp = IPtxt.toCharArray();
		char []resultOfIP = InitialPermutation(IPtxt_tmp);//明文IP初始置换
		char[] afterIPRi = new char[32];
		char[] afterIPLi = new char[32];
		
 		for(int i=0;i<32;i++){//获得初始L0和R0
			afterIPLi[i] = resultOfIP[i];
			afterIPRi[i] = resultOfIP[i+32];
		}

 		char[] resultRi = afterIPRi;
 		char[] resultLi = afterIPLi;
 
		for(int i=0;i<16;i++){//循环16次
			char[]resultRitmp = resultRi;
			char[]resultLitmp = resultLi;
			resultLi = resultRitmp;//Li = Ri-1

			char[] FOut = EcryptFunction(resultRitmp,listKi.get(i));
			resultRi = XorAandB(resultLitmp,FOut);
		}
		char[] finalCircleResult = new char[64];
		for(int i=0;i<32;i++){
			finalCircleResult[i] = resultLi[i];
			finalCircleResult[32+i] = resultRi[i];
		}
		
		char[] resultEncrypted = ReverseInitialPermutation(finalCircleResult);
		
		return resultEncrypted;
	}
	//DES 16轮解密圈变换
	public static char[] DecryptCircleTrans(String Encrypted,ArrayList<char[]> listKi){
		char[] IEncrypted_tmp = Encrypted.toCharArray();
		char []resultOfIP = InitialPermutation(IEncrypted_tmp);//密文IP-1逆置换
		char[] afterIPRi = new char[32];
		char[] afterIPLi = new char[32];
		
 		for(int i=0;i<32;i++){//获得初始L16和R16
			afterIPLi[i] = resultOfIP[i];
			afterIPRi[i] = resultOfIP[i+32];
		}
 		
 		char[] resultRi = afterIPRi;
 		char[] resultLi = afterIPLi;
 
		for(int i=15;i>=0;i--){//循环16次
			char[]resultRitmp = resultRi;
			char[]resultLitmp = resultLi;
			resultRi = resultLitmp;//Ri-1 = Li
			
			char[] FOut = EcryptFunction(resultLitmp,listKi.get(i));
			resultLi = XorAandB(resultRitmp,FOut);
		}
		char[] finalCircleResult = new char[64];
		for(int i=0;i<32;i++){
			finalCircleResult[i] = resultLi[i];
			finalCircleResult[32+i] = resultRi[i];
		}
		
		char[] resultDecrypted = ReverseInitialPermutation(finalCircleResult);
		
		return resultDecrypted;
	}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值