密码学DES加密解密源代码.docx
《密码学DES加密解密源代码.docx》由会员分享,可在线阅读,更多相关《密码学DES加密解密源代码.docx(19页珍藏版)》请在冰点文库上搜索。
密码学DES加密解密源代码
对DES算法加密解密过程图示的说明如下:
待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:
IP
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
R16与L16合并成64位的比特串。
值得注意的是R16一定要排在L16前面。
R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表如下:
IP-1
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
程序源代码:
#include"encryption.h"
#include
#include
usingnamespacestd;
//下面进行s盒的初始化。
//初始化八个s盒。
intsbox[8][4][16]={
{{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}},//sbox0].s_box[4][16]
{{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}},//sbox[1].s_box[4][16]
{{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,12,3,11,5,2,12}},//sbox[2].s_box[4][16]
{{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}},//sbox[3].s_box[4][16]
{{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}},//sbox[4].s_box[4][16]
{{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}},//sbox[5].s_box[4][16]
{{4,11,2,14,15,0,8,13,3,13,9,7,5,10,6,1},
{13,0,11,7,4,9,1,10,14,2,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}},//sbox[6].s_box[4][16]
{{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}}
};/*//sbox[7].s_box[4][16]*/
//
//hexbin的初始化,定义二进制与十六进制之间的对应关系。
//定义结构体数组存放十六进制的0~9,a~f及它们对应的二进制的关系。
HEXBINhexbin[]=
{
{0,0,0,0},//hexbin[0]
{0,0,0,1},//hexbin[1]
{0,0,1,0},//hexbin[2]
{0,0,1,1},//hexbin[3]
{0,1,0,0},//hexbin[4]
{0,1,0,1},//hexbin[5]
{0,1,1,0},//hexbin[6]
{0,1,1,1},//hexbin[7]
{1,0,0,0},//hexbin[8]
{1,0,0,1},//hexbin[9]
{1,0,1,0},//hexbin[10]
{1,0,1,1},//hexbin[11]
{1,1,0,0},//hexbin[12]
{1,1,0,1},//hexbin[13]
{1,1,1,0},//hexbin[14]
{1,1,1,1}//hexbin[15]
};
constcharHEX[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
voidhex2binary(conststring&str,int*binary);//将输入的明文和密钥串(16进制)转换为二进制,依次存放到明文和密钥数组中去。
voidoutput(int*array,intlength);//一般的打印数组的函数,每8个数一行
voiddisplay(int*array,intlength);//打印扩展的R0,每六个数一行
voidshow(int*array,intlength);//第三个数组打印版本,最后才输出换行
voidInitial_Permunation(int*plain,int*l,int*l0);//初始置换IP,将明文分成等长的两部分,赋给L0和R0。
第一个参数为明文数组,第二个为L或R,即置换规则,第三个参数为L0或R0,即初始的两个分组。
voidextension(int*r,int*ri,int*err,intlength);//对R0进行扩展,从32位扩展到48位.第一个参数用来存放进行扩展后的R0(用ER数组来存放),第二个参数为扩展前的R0,第三个参数为扩展规则
voidpermunationChoose1(int*k,int*c,int*c0,intlength);//置换选择PC:
子密钥的获取,C0和D0分开获取.第一个参数指示总密钥,第二个参数指明密钥获取规则C或D,第三个参数用来存放初始的分密钥C0或D0,第四个参数指示分密钥的长度
int*keyObtain(int*k,int*c,int*c0,int*d,int*d0,intlength);//子密钥的获取,调用其他函数。
voidrotateLeft(intnumber,int*k,int*cl,intlength);//子密钥循环左移,移位后的C0和D0发生改变,所以要重新赋值。
number指示第几轮迭代,CL[number]指示循环移位的次数。
length用于动态创建数组时指定大小
voidcopyArray(int*dst,int*src,intlength);//将src数组中的元素复制到dst中。
voidmergeKey(int*c,int*d,int*k,intlength);//将两部分的密钥合并到一起(C0和D0),为了移位时使用
voidkeyConverse(int*k1,int*k2,intlength);//计算中数组下标的处理,将数组长度加1,0号元素空出来。
voidpermunationChoose2(int*k,int*k1,int*pc,intlength);//PC2:
置换选择2,从56bit的密钥中选取48位,作为当前的子密钥。
voidexclusive_or(int*r,int*k,int*ex_or,intlength);//函数功能:
将扩展后的R0与子密钥进行扩展。
r为E(R0),k为子密钥,ex_or用来存放异或后的数组,存到Exclusive_or数组中。
voidSbox(int*ex_or,int*as,intlength);//s盒替换,将48位还原为32位。
对每一行的六个位,进过s盒置换后转换为4位。
ex_or存放异或后的结果,sbox存放S盒,as存放32位的结果,length为8
voidpermunation(int*as,int*permunation,intlength);//P置换,输入为s盒替换后的32位信息和置换数组,长度为32。
voidultimate_result(int*li,int*pas,intlength);//最后将p置换的结果与Li-1进行异或,得出Ri。
其中li为Li-1,pas为p置换后的结果。
length为32
voidresult2Hex(string&str,int*res,intlength);//将最后的二进制密文转换成16进制的密文,存放到str中。
voidmain()
{
cout<<"DES加密算法"<cout<<"输入十六位的明文序列,由0~9,a~f组成"<stringplain_text;
cin>>plain_text;
cout<hex2binary(plain_text,P);
Initial_Permunation(P,L,L0);
cout<<"输入十六位的密钥序列,由0~9,a~f组成"<stringkey;
cin>>key;
cout<hex2binary(key,K);
Initial_Permunation(P,R,R0);//初始置换,生成L0和R0
extension(ER,R0,ERR,array_elements(ERR));
exclusive_or(ER,keyObtain(K,C,C0,D,D0,N1),Exclusive_or,array_elements(ER)-1);//密钥数组从0开始存放,ER数组从1开始存放元素。
Sbox(Exclusive_or,AS,E);
permunation(AS,PERMUNATION,S);
ultimate_result(L0,PAS,S);
mergeKey(CipherR,R0,CipherText,S+1);//L1=R0
result2Hex(CipherHex,CipherText,array_elements(CipherText));
cout<<"密文字符如下所示:
"<cout<system("pause");
}
voidhex2binary(conststring&str,int*binary)
{
intcount=1;
for(sizetypeindex=0;index!
=str.size();++index)
{
switch(str[index])
{
case'0':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[0].binary[i];
++count;
}
}
break;
case'1':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[1].binary[i];
++count;
}
}
break;
case'2':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[2].binary[i];
++count;
}
}
break;
case'3':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[3].binary[i];
++count;
}
}
break;
case'4':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[4].binary[i];
++count;
}
}
break;
case'5':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[5].binary[i];
++count;
}
}
break;
case'6':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[6].binary[i];
++count;
}
}
break;
case'7':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[7].binary[i];
++count;
}
}
break;
case'8':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[8].binary[i];
++count;
}
}
break;
case'9':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[9].binary[i];
++count;
}
}
break;
case'a':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[10].binary[i];
++count;
}
}
break;
case'b':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[11].binary[i];
++count;
}
}
break;
case'c':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[12].binary[i];
++count;
}
}
break;
case'd':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[13].binary[i];
++count;
}
}
break;
case'e':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[14].binary[i];
++count;
}
}
break;
case'f':
{
for(inti=0;i!
=4;++i)
{
binary[count]=hexbin[15].binary[i];
++count;
}
}
break;
default:
break;
}
}
}
voidInitial_Permunation(int*plain,int*l,int*l0)
{
intcount=1;
for(inti=0;i!
=4;++i)
{
for(intj=0;j!
=8;++j)
{
l0[count]=plain[l[count]];
++count;
}
}
}
voidextension(int*r,int*ri,int*err,intlength)
{
intcount=1;
for(count;count<=length;++count)
{
r[count]=ri[err[count]];
}
}
voidpermunationChoose1(int*k,int*c,int*c0,intlength)
{
intcount=1;
for(count;count<=length;++count)
{
c0[count]=k[c[count]];
}
}
int*keyObtain(int*k,int*c,int*c0,int*d,int*d0,intlength)
{
permunationChoose1(k,c,c0,length);
permunationChoose1(k,d,d0,length);
mergeKey(C0,D0,MergeK,array_elements(C0));
rotateLeft(1,MergeK,CL,array_elements(MergeK));
keyConverse(MergeK1,MergeK,array_elements(MergeK));
permunationChoose2(MergeKPC2,MergeK1,PC2,array_elements(MergeKPC2));
returnMergeKPC2;
}
voidrotateLeft(intnumber,int*k,int*cl,intlength)
{
int*temp=newint[length];//临时数组,用来存放密钥,最后复制到K中。
intt=cl[number];//保存移位次数。
for(inti=0;i{
temp[(i-t+length)%length]=MergeK[i];
}
copyArray(MergeK,temp,length);
}
voidmergeKey(int*c,int*d,int*k,intlength)
{
intcount=0;//其他的数组都是从1开始存放元素,融合