SDES(Simple Data Encryption Standard)加密算法——Java实现

一.SDES加密算法

SDES(Simple Data Encryption Standard)加密算法——Java实现_第1张图片

SDES的算法如上图所示,作者将其分为三个部分讲解:

1.子密钥的产生
        1.1  对于输入的10位密钥K=(k1,k2,k3,k4,k5,k6,k7,k8,k9,k10),做P10置换,得到结果为K1=(k3,k5,k2,k7,k4,k10,k1,k9,k8,k6)。
        1.2  将上一步中的K1分成LK1和RK1分别对应K1的高低5位,并将LK1和RK1做循环左移1位的操作,例:(10010)循环左移1位变为(00101)。
        1.3  合并LK1和RK1得到10位的K2(高5位为LK1,低5位为RK1),对K2=(K1,k2,k3,k4,k5,k6,k7,k8,k9,k10)做P8置换,得到子密钥SubKey1=(k6,k3,k7,k4,k8,k5,k10,k9)。
        1.4  将上一步中的K2分成LK2和RK2分别对应K2的高低5位,并将LK2和RK2做循环左移2位的操作,例:(10010)循环左移2位变为(01010)。
        1.5  合并LK2和RK2得到10位的K3(高5位为LK2,低5位为RK2),对K3=(k1,k2,k3,k4,k5,k6,k7,k8,k9,k10)做P8置换,得到子密钥SubKey2=(k6,k3,k7,k4,k8,k5,k10,k9)。

2.加密部分

         2.1  对于输入的8位明文P=(p1,p2,p3,4,p5,p6,p7,p8),首先做一次IP置换得到P1=(k2,k6,k3,k1,k4,k8,k5,k7),IP置换相当于对P进行矩阵的乘法,对应矩阵为:


        IP的逆变换IPI可以同样可以看成是矩阵的乘法,对应的矩阵为:

SDES(Simple Data Encryption Standard)加密算法——Java实现_第2张图片

        2.2  得到P1以后开始,进入Fk函数进行处理,这是SDES加密的核心部分,也是最为复杂的部分,对应的fk函数为:

        

        其中:
        (1)   L,R分别为P1的高低4位;
        (2)   E/P为一个4位到8位的变换,变换结果为E/P(p1,p2,p3,p4)=(p4,p1,p2,p3,p2,p3,p4,p1)

        (3)  S0&S1是指对E/P变换的8位结果的高低4位,分别做S盒变换得到两个2位数,然后合并成新的4位数,其中S0和S1分别为:   

SDES(Simple Data Encryption Standard)加密算法——Java实现_第3张图片

        S0用于对高4位做变换,S1用于对低4位做变换,变换的过程为将4位的输入数的第0位(设为a),第3位(设为b)结合成新的数i,结合方式为i=a*2+b,以同样的方式将4位输入数的第2位,第4位结合成新的数j,然后用Sij(就是S盒中的S[i][j],两位数,最大为3)取代原来的4位数,例如:S0(1,1,0,1)=S0[2][1]=1=(01),红色标记处。

         (4)连接S0得到2位和S1得到2位,得到4位数,并做P4变换,P4变换的结果为P4(p1,p2,3,4)=(p2,p4,p3,p1)

        (5)上述操作都是在输入明文的R部分做的,操作完成后与L进行异或,得到新的4位数,最后于原始的R合并成8位中间态。

        fk函数对应的细节,如下图所示:

SDES(Simple Data Encryption Standard)加密算法——Java实现_第4张图片

                  图2     fk函数细节
        2.3   Fk函数的结果是8位数字P2=(p1,p2,p3,p4,p5,p6,p7,p8),对其执行SW置换,置换结果是交换P2的高低4位,即得到P3=(p5,p6,p7,p8,p1,p2,p3,p4)。
        2.4   对P3再次执行Fk函数得到P4,然后对P4执行IP的逆操作,即得到最终的8位密文。
3.解密部分
解密部分与加密部分操作的逆过程,可以参照图1实现,此处不再赘述。

二.SDES算法实现

/***********************************************************
 *作者: chw1989
 *日期:2012.4.5
 *邮箱:[email protected]
 ***********************************************************/
public class SDES{
		static int SubKey1=0;
		static int SubKey2=0;
		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 IP8[]=new int[]{2,6,3,1,4,8,5,7};
		static int IP8I[]=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},
		};
		
		//通过连续位操作进行数据变换,区别于C++版本的通过矩阵乘的方式实现数据变换
		static int Transformation(int FromNuber,int P_Vector[],int NumberLen){
			int ToNumber=0;
			for(int i=0;i<P_Vector.length;i++){
				ToNumber<<=1;
				ToNumber|=(FromNuber>>(NumberLen-P_Vector[i]))&1;
			}
			return ToNumber;
		}
		
		static void SetKey(int Key){
			int WorkKey,LKey,RKey;
			WorkKey=Transformation(Key,P10,10);
			LKey=WorkKey>>5;//右移5位取出高(左)5位的值
			RKey=WorkKey & 0x1f;//和"0000011111"做与运算,可以取出低(左)5位的值
			
			//循环左移1位,相当于先右移4位,取出最高位,然后与"0000001111"做与运算,
			//并右移1位,最后做或运算,即可得到循环右移1位的结果
			LKey=(LKey>>4) | ((LKey & 0xf)<<1);//循环左移1位
			RKey=(RKey>>4) | ((RKey & 0xf)<<1);//循环左移1位
			WorkKey=(LKey<<5) | RKey;
			SubKey1=Transformation(WorkKey,P8,10);
			LKey=WorkKey>>5;//右移5位取出高(左)5位的值
			RKey=WorkKey&0x1f;//和"0000011111"做与运算,可以取出低(左)5位的值
			LKey=(LKey>>3) | ((LKey & 0x7)<<2);//循环左移2位
			RKey=(RKey>>3) | ((RKey & 0x7)<<2);//循环左移2位
			WorkKey=(LKey<<5) | RKey;//合并左右5位
			SubKey2=Transformation(WorkKey,P8,10);
		}
        
		static int Fk(int InputText,int SubKey){//Fk函数
			int LText,RText,WorkText;
			WorkText=Transformation((InputText & 0xf),EP,4);//EP,4位到8位的转化函数
			WorkText^=SubKey;//与子密钥做异或操作
			LText=WorkText>>4;//取出高4位
			RText=WorkText & 0xf;//取出低4位
			//下面是两个S盒变换
			LText=S0[((LText & 0x8)>>2) | (LText & 1)][(LText>>1) & 0x3];
			RText=S1[((RText & 0x8)>>2) | (RText & 1)][(RText>>1) & 0x3];
			//合并成4位
			WorkText=LText<<2 | RText;
			WorkText=Transformation(WorkText,P4,4);//4位变换
			LText=InputText>>4;
			RText=InputText & 0xf;
			WorkText=LText^WorkText;//左4位与中间值做异或
			WorkText<<=4;
			WorkText|=RText;//合并成8位
			return WorkText;
		}
		
		static int SW(int FromNumber){//高4位与低4位交换
			return(((FromNumber & 0xf)<<4) | (FromNumber>>4));
		}
		
		static int Cipher(int FromText){//加密函数
			int ToText;
			ToText=Transformation(FromText,IP8,8);
			ToText=Fk(ToText,SubKey1);
			ToText=SW(ToText);
			ToText=Fk(ToText,SubKey2);
			ToText=Transformation(ToText,IP8I,8);
			return ToText;
		}
		
		static int InvCipher(int FromText){//解密函数
			int ToText;
			ToText=Transformation(FromText,IP8,8);
			ToText=Fk(ToText,SubKey2);
			ToText=SW(ToText);
			ToText=Fk(ToText,SubKey1);
			ToText=Transformation(ToText,IP8I,8);
			return ToText;
		}
		
		public static void main(String[] args){//测试函数
			int a='a';
			SetKey(1017);
			System.out.println(a);
			int b=Cipher(a);
			System.out.println(b);
			int c=InvCipher(b);
			System.out.println(c);
		}
}


三.运行截图

SDES(Simple Data Encryption Standard)加密算法——Java实现_第5张图片

四.总结

    SDES密钥长度只有10位,相对来说是非常短的,遍历一遍可能只需要零点几秒的时间,不能用于实际的加密工作,但是该算法适合于教学和加密算法入门学习之用。

你可能感兴趣的:(java,加密,算法,vector,encryption,transformation)