西电网络安全实验.docx
《西电网络安全实验.docx》由会员分享,可在线阅读,更多相关《西电网络安全实验.docx(31页珍藏版)》请在冰豆网上搜索。
西电网络安全实验
《计算机与网络安全》课程实验
2016年月6月
实验一DES加解密算法的实现
一、实验目的及任务:
掌握DES加密算法的加解密过程。
二、实验环境
VC或TC编程环境;主机操作系统为Windows2000或WindowsXP;
三、实验原理
要深入理解对称加密算法,掌握DES加密过程。
具备一定的C语言编程技
能。
DES(DataDES(DataEncryptionStandard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。
DES算法以被应用于许多需要安全加密的场合。
(一)、密钥生成
1、变换密钥
取得64位的密钥,每个第8位作为奇偶校验位。
2、变换密钥。
(1)、舍弃64位密钥中的奇偶校验位,根据下表(PC-1)进行密钥变换得到56位的密钥,在变换中,奇偶校验位以被舍弃。
(2)、将变换后的密钥分为两个部分,开始的28位称为C[0],最后的28位称为D[0]。
(3)生成16个子密钥,初始I=1。
(i)、同时将C[I]、D[I]左移1位或2位,根据I值决定左移的位数。
(ii)、将C[I]D[I]作为一个整体按下表(PC-2)变换,得到48位的K[I]
(iii)、从1-2-3-1处循环执行,直到K[16]被计算完成。
(二)、处理64位的数据
1、取得64位的数据,如果数据长度不足64位,应该将其扩展为64位(例如补零)
2、将64位数据按下表变换(IP)
3、将变换后的数据分为两部分,开始的32位称为L[0],最后的32位称为R[0]。
4、用16个子密钥加密数据,初始I=1。
(1)、将32位的R[I-1]按下表(E)扩展为48位的E[I-1]
(2)、异或E[I-1]和K[I],即E[I-1]XORK[I]
(3)、将异或后的结果分为8个6位长的部分,第1位到第6位称为B[1],第7位到第12位称为B[2],依此类推,第43位到第48位称为B[8]。
(4)、按S表变换所有的B[J],初始J=1。
所有在S表的值都被当作4位长度处理。
(i)将B[J]的第1位和第6位组合为一个2位长度的变量M,M作为在S[J]中的行号。
(ii)、将B[J]的第2位到第5位组合,作为一个4位长度的变量N,N作为在S[J]中的列号。
(iii)、用S[J][M][N]来取代B[J]。
(iv)、从(i)处循环执行,直到B[8]被替代完成。
(5)、将B[1]到B[8]组合,按下表(P)变换,得到P。
(6)、异或P和L[I-1]结果放在R[I],即R[I]=PXORL[I-1]。
(7)、L[I]=R[I-1]
(8)、从2-4-1处开始循环执行,直到K[16]被变换完成。
5、、组合变换后的R[16]L[16](注意:
R作为开始的32位),按下表(IP-1)变换得到最后的结果。
四、实验步骤
利用编程语言实现DES加解密算法。
1、编程
2、调试
3、运行结果
4、存盘
五、实验结果
加密:
Key:
0x300x300x300x30......0x30(8个字节)
Data:
0x310x310x310x31......0x31(8个字节)
Mode:
Encryption
结果:
655ea628cf62585f
解密:
Key:
0x310x31......0x31(8个0x31)
Data:
655ea628cf62585f
Mode:
Decryption
结果:
0x310x31......0x31(8个0x31)
六、实验思考题
DES算法主要有哪几部分?
可以画出流程
一轮迭代过程:
七、DES源程序
#include"memory.h"
#include"stdio.h"
#include
usingnamespacestd;
enum{encrypt,decrypt};//ENCRYPT:
加密,DECRYPT:
解密
voiddes_run(intout[8],intin[8],booltype=encrypt);
//设置密钥
voiddes_setkey(constintkey[8]);
staticvoidf_func(boolin[32],constboolki[48]);//f函数
staticvoids_func(boolout[32],constboolin[48]);//s盒代替
//变换
staticvoidtransform(bool*out,bool*in,constint*table,intlen);
staticvoidtrans(bool*out,bool*in);
staticvoidXOR(bool*ina,constbool*inb,intlen);//异或
staticvoidrotatel(bool*in,intlen,intloop);//循环左移
staticvoidbytetobit1(bool*out,constint*in,intbits);
//位组转换成字节组
staticvoidbittobyte1(int*out,constbool*in,intbits);
staticvoidbytetobit(bool*out,constint*in,intbits);
//置换IP表
conststaticintip_table[64]={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};
//逆置换IP-1表
conststaticintipr_table[64]={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};
//E位选择表
staticconstinte_table[48]={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};
//P换位表
conststaticintp_table[32]={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};
//pc1选位表
conststaticintpc1_table[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
};
//pc2选位表
conststaticintpc2_table[48]={
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
};
//左移位数表
conststaticintloop_table[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//S盒
conststaticints_box[8][4][16]={
//s1
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
};
staticboolsubkey[16][48];//16圈子密钥
voiddes_run(intout[8],intin[8],booltype)
{
//for(inti=0;i<8;i++)
//printf("%d",in[i]);
//printf("\n");
staticboolm[64],tmp[32],*li=&m[0],*ri=&m[32];
bytetobit1(m,in,64);
transform(m,m,ip_table,64);
/*for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
cout<}
cout<}
cout<if(type==encrypt)
{
for(inti=0;i<16;i++)
{
memcpy(tmp,ri,32);
f_func(ri,subkey[i]);
XOR(ri,li,32);
memcpy(li,tmp,32);
}
trans(m,m);
}
else{
trans(m,m);
for(inti=15;i>=0;i--){
memcpy(tmp,li,32);
f_func(li,subkey[i]);
XOR(li,ri,32);
memcpy(ri,tmp,32);
}
}
/*for(inti=0;i<8;i++)
{
for(intj=0;j<8;j++)
{
cout<}
cout<}
cout<transform(m,m,ipr_table,64);
bittobyte1(out,m,64);
}
voiddes_setkey(constintkey[8])
{
staticboolk[64],*kl=&k[0],*kr=&k[28];
bytetobit1(k,key,64);
transform(k,k,pc1_table,56);
for(inti=0;i<16;i++)
{
rotatel(kl,28,loop_table[i]);
rotatel(kr,28,loop_table[i]);
transform(subkey[i],k,pc2_table,48);
}
}
voidf_func(boolin[32],constboolki[48])
{
staticboolmr[48];
transform(mr,in,e_table,48);
XOR(mr,ki,48);
s_func(in,mr);
transform(in,in,p_table,32);
}
voids_func(boolout[32],constboolin[48])
{
for(inti=0,j,k;i<8;i++,in+=6,out+=4)
{
j=(in[0]<<1)+in[5];
k=(in[1]<<3)+(in[2]<<2)+(in[3]<<1)+in[4];
bytetobit(out,&s_box[i][j][k],4);
}
}
voidtransform(bool*out,bool*in,constint*table,intlen)
{
staticbooltmp[256];
for(inti=0;itmp[i]=in[table[i]-1];
memcpy(out,tmp,len);
}
voidtrans(bool*out,bool*in)
{
booltemp[32];
memcpy(temp,in,32);
memcpy(out,in+32,32);
memcpy(out+32,temp,32);
}
voidXOR(bool*ina,constbool*inb,intlen)
{
for(inti=0;iina[i]^=inb[i];
}
voidrotatel(bool*in,intlen,intloop)
{
staticbooltmp[256];
memcpy(tmp,in,loop);
memcpy(in,in+loop,len-loop);
memcpy(in+len-loop,tmp,loop);
}
voidbytetobit(bool*out,constint*in,intbits)
{
for(inti=0;iout[i]=(in[i/8]>>(3-i%8))&1;
}
voidbytetobit1(bool*out,constint*in,intbits)
{
for(inti=0;iout[i]=(in[i/8]>>(7-i%8))&1;
}
voidbittobyte1(int*out,constbool*in,intbits)
{
memset(out,0,8*sizeof(int));
for(inti=0;iout[i/8]|=in[i]<<(7-i%8);
}
intmain()
{
intkey[8],str[8];
inti;
puts("pleaseinputyourwords");
for(i=0;i<8;i++)
{
cin>>hex>>str[i];
}
puts("pleaseinputyourkey");
for(i=0;i<8;i++)
{
cin>>hex>>key[i];
}
printf("\n");
des_setkey(key);
des_run(str,str,encrypt);
puts("afterencrypting:
");
for(i=0;i<8;i++)
{
cout<}
printf("\n");
puts("afterdecrypting:
");
des_run(str,str,decrypt);
for(i=0;i<8;i++)
{
cout<}
printf("\n");
return0;
}
实验二RSA加解密算法的实现
一、实验目的及任务:
掌握RSA加密算法的加解密过程。
二、实验环境
VC或TC编程环境;主机操作系统为Windows2000或WindowsXP;
三、实验原理
RSA加密算法是一种非对称加密算法。
在公钥加密标准和电子商业中RSA
被广泛使用。
RSA是1977年由罗纳德·李维斯特(RonRivest)、阿迪·萨莫尔、(AdiShamir)和伦纳德·阿德曼(LeonardAdleman)一起提出的。
当时他们三
人都在麻省理工学院工作。
RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法的可靠性基于分解极大的整数是很困难的。
假如有人找到一种很快的分解因子的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。
但找到这样的算法的可能性是非常小的。
今天只有短的RSA钥匙才可能被强力方式解破。
到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。
只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
1、公钥和私钥的产生
假设Alice想要通过一个不可靠的媒体接收Bob的一条私人讯息。
她可以用以下的方式来产生一个公钥和一个密钥:
随意选择两个大的质数p和q,p不等于q,计算N=pq。
根据欧拉函数,不大于N且与N互质的整数个数为(p-1)(q-1)
选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1)
用以下这个公式计算d:
d×e≡1(mod(p-1)(q-1))
将p和q的记录销毁。
e是公钥,d是私钥。
d是秘密的,而N是公众都知道的。
Alice将她的公钥传给Bob,而将她的私钥藏起来。
2、加密消息
假设Bob想给Alice送一个消息m,他知道Alice产生的N和e。
他使用起先与Alice约好的格式将m转换为一个小于N的整数n,比如他可以将每一个字转换为这个字的Unicode码,然后将这些数字连在一起组成一个数字。
假如他的信息非常长的话,他可以将这个信息分为几段,然后将每一段转换为n。
用下面这个公式他可以将n加密为c:
计算c并不复杂。
Bob算出c后就可以将它传递给Alice。
3、解密消息
Alice得到Bob的消息c后就可以利用她的密钥d来解码。
她可以用以下这个公式来将c转换为n:
得到n后,她可以将原来的信息m重新复原。
解码的原理是
以及ed≡1(modp-1)和ed≡1(modq-1)。
费马小定理证明
和
这说明(因为p和q是不同的质数)
四、实验步骤
1、求素数p和q
2、求公钥(e,n):
e与ψ(n)=(p-1)(q-1)互质
3、求私钥(d,n):
d×e≡1(mod(p-1)(q-1))
4、加密过程:
c=(Me)modn
5、解密过程:
m=(Cd)modn
五、实验结果
找两个素数:
p=47q=59
n=p*q=2773,t=(p-1)*(q-1)=2668
寻找e满足e1:
加密m=465,得C=1118
2:
解密C=1118,得m=465
六、思考题
RSA算法主要有哪几部分?
1、输入p和q,并求出公钥(e,n):
e与ψ(n)=(p-1)(q-1)互质,再求出私钥(d,n):
d×e≡1(mod(p-1)(q