信息系统安全实验指导书.docx
《信息系统安全实验指导书.docx》由会员分享,可在线阅读,更多相关《信息系统安全实验指导书.docx(19页珍藏版)》请在冰豆网上搜索。
信息系统安全实验指导书
《信息系统安全》课程实验指导书
实验学时:
课内实验18学时
实验类型:
验证性
实验要求:
必修
适用对象:
软件工程
实验一:
古典密码算法---代换技术(4学时)
一、实验目的
通过本实验的学习,使学生编程实现古典密码算法中的代换密码技术,培养学生的编程能力和对基础算法的理解,加深对古典密码体制技术的了解,为今后继续深入现代密码学的学习奠定基础。
二、实验内容
实现代换密码的加解密;
三、实验原理、方法和手段
古典密码算法历史上曾被广泛应用,大都使用手工和机械操作来实现加密和解密,比较简单。
古典密码主要是利用密码算法实现文字信息的加密和解密,本实验运用两种常见的具有代表性的古典密码技术---代换密码技术,以帮助学生对密码算法建立一个初步的认识和印象。
代换密码:
代换密码算法的原理是使用替代法进行加密,就是将明文中的字符用其它字符替代后形成密文。
例如:
明文字母a,b,c,d,用D,E,F,G做对应替换后形成密文。
代换密码包括多种类型,如单表替代密码,多明码替代密码,多字母替代密码,多表替代密码等.本实验利用一种典型的单表替代密码---恺撒(caesar)密码,又叫循环移位密码,加密方法是将明文中的每个字符,用此字符在字母表中后面第k个字母替代,加密过程可以表示为下面的函数:
E(m)=(m+k)modn
其中:
m为明文字母在字母表中的位置数;n为字母表中的字母个数;k为密钥;E(m)为密文字母在字母表中对应的位置数。
例如,对于明文字母H,其在字母表中的位置数为8,设k=4,则按照上式计算出来的密文为L:
E(8)=(m+k)modn=(8+4)mod26=12=L
四、实验环境、条件
运行Windows7操作系统的PC机,具有C语言编译环境。
五、实验组织运行要求
根据本实验的特点、要求和具体条件,采用以学生自主训练为主的开放模式组织教学,每个学生按照实验指导书,独立完成实验。
六、实验步骤
根据实验原理部分对凯撒密码算法的介绍,自己创建明文信息,并选择一个密钥k,编写凯撒密码算法的实现程序,实现加密和解密操作.
参考程序:
1.加密:
K=4
2.解密密文:
VSRQJHEREVTXDUHSDQWYU:
defdecrypt_password(password,offset)
pwdLength=len(password)
pwd=""
forindexinrange(pwdLength):
ascciiNum=ord(password[index])-65+offset
ascciCha=chr(ascciiNum%26+65)
pwd+=str(ascciCha)
returnpwd
forindexinrange(0,26):
printdecrypt_password("VSRQJHEREVTXDUHSDQWU",-3).lower()
明文为:
spongebobsquarepantr
七、实验报告
本实验为古典密码学算法的验证类实验,需要按实验报告模板的表格填写,具体要求如下:
(1)实验总结要反映实验步骤中的结果,并提供文字描述。
(2)除教师评语外,实验报告表中的每项内容均由本实验的同学填写。
(3)实验总结和实验自我评语,严禁雷同。
(4)实验报告需要按实验报告模板的格式进行填写。
实验二:
古典密码算法---置换技术(4学时)
一、实验目的
通过本实验的学习,使学生编程实现古典密码算法中的置换密码技术,培养学生的编程能力和对基础算法的理解,加深对古典密码体制技术的了解,为今后继续深入现代对称密码学的学习奠定基础。
二、实验内容
实现置换密码的加解密。
三、实验原理、方法和手段
古典密码算法历史上曾被广泛应用,大都使用手工和机械操作来实现加密和解密,比较简单。
古典密码主要是利用密码算法实现文字信息的加密和解密,本实验运用常见的具有代表性的古典密码技术---置换密码技术,以帮助学生对密码算法建立一个初步的认识和印象。
置换密码:
置换密码又称为换位密码,算法的原理是不改变、替换明文字符,只将字符在明文中的排列顺序改变,从而实现明文信息的加密。
矩阵换位法是实现置换密码的一种常用方法(类似于教材中的双换位密码)。
它将明文中的字母按照给定的顺序安排在一个矩阵中,然后用根据密钥提供的顺序重新组合矩阵中字母,从而形成密文。
例如,明文为attackbeginsatfive,密钥为cipher,将明文按照每行6列的形式排在矩阵中,形成如下形式:
attack
begins
atfive
根据密钥cipher中各字母在字母表中出现的先后顺序,给定一个置换:
123456
F=
145326
根据上面的置换,将原有矩阵中的字母按照第1列,第4列,第5列,第3列,第2列,第6列的顺序排列,则有下面形式:
aacttk
binges
aivfte
从而得到密文:
abatgftetcnvaiikse
其解密的过程是根据密钥的字母数作为列数,将密文按照列,行的顺序写出,再根据由密钥给出的矩阵置换产生新的矩阵,从而恢复明文。
四、实验环境、条件
运行Windows操作系统的PC机,具有C语言、C++编译环境。
五、实验组织运行要求
根据本实验的特点、要求和具体条件,采用以学生自主训练为主的开放模式组织教学,每个学生按照实验指导书,独立完成实验。
六、实验步骤
根据实验原理部分对置换密码算法的介绍,自己创建明文信息,并选择一个密钥,编写置换密码算法的实现程序,实现加密和解密操作.
七、实验报告
本实验为古典密码学算法的验证类实验,需要按实验报告模板的表格填写,具体要求如下:
(1)实验总结须反映实验步骤中的结果,并提供文字描述。
(2)除教师评语外,实验报告表中的每项内容均由本实验的同学填写。
(3)实验总结和实验自我评语,严禁雷同。
(4)实验报告需要按实验报告模板的格式进行填写。
实验三:
DES加解密算法的实现(6学时)
一、实验目的
通过本实验的学习,使学生学会编程实现DES加解密算法,培养学生的编程能力和对DES算法的理解,深入理解对称加密算法和Feistel结构,为今后继续深入对称和非对称密码学的学习奠定基础。
二、实验内容
实现DES算法的加解密。
三、实验原理、方法和手段
DES(DataEncryptionStandard)算法,于1977年得到美国政府的正式许可,是一种用56位密钥来加密64位数据的方法。
DES算法以被应用于许多需要安全加密的场合。
1.DES加密:
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则见下表:
58,50,12,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,
即将输入的第58位换到第一位,第50位换到第2位,……,依此类推,最后一位是原来的第7位。
L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,
经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,即得到密文输出。
16轮的迭代:
F函数如下:
8个S盒:
逆置换正好是初始置的逆运算,例如,第1位经过初始置换后,处于第40位,而通过逆置换,又将第40位换回到第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,5826,33,1,41,9,49,17,57,25,
2.子密钥的生成算法:
子密钥Ki(48bit)的生成算法初始Key值为64位,但DES算法规定,其中第8、16、......64位是奇偶校验位,不参与DES运算。
故Key实际可用位数便只有56位。
将56位分为C0、D0两部分,各28位,然后分别进行第1次循环左移,得到C1、D1,将C1(28位)、D1(28位)合并得到56位,再经过缩小选择换位2,从而便得到了密钥K0(48位)。
依此类推,便可得到K1、K2、......、K16。
置换选择1置换选择2
需要注意的是,16次循环左移对应的左移位数要依据下述规则进行:
循环左移位数1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
DES算法的解密过程是一样的,区别仅仅在于第一次迭代时用子密钥K16,第二次K14、……,最后一次用K1,算法本身并没有任何变化。
四、实验环境、条件
运行Windows操作系统的PC机,具有C语言、C++编译环境。
五、实验组织运行要求
根据本实验的特点、要求和具体条件,采用以学生自主训练为主的开放模式组织教学,每个学生按照实验指导书,独立完成实验。
六、实验步骤
利用编程语言实现DES加解密算法。
1、编程:
包含的功能函数有:
staticvoidDES(charOut[8],charIn[8],constSUBKEY_Ppskey,boolType);//标准DES加/解密
staticvoidSETKEY(constchar*Key,intlen);//设置密钥
staticvoidSet_SubKey(SUBKEY_Ppskey,constcharKey[8]);//设置子密钥
staticvoidF_FUNCTION(boolIn[32],constboolKi[48]);//f函数完成扩展置换、S-盒代替和P盒置换
staticvoidS_BOXF(boolOut[32],constboolIn[48]);//S-盒代替函数
staticvoidTRANSFORM(bool*Out,bool*In,constchar*Table,intlen);//变换函数
staticvoidXOR(bool*InA,constbool*InB,intlen);//异或函数
staticvoidCYCLELEFT(bool*In,intlen,intloop);//循环左移函数
staticvoidByteToBit(bool*Out,constchar*In,intbits);//字节组转换成位组函数
staticvoidBitToByte(char*Out,constbool*In,intbits);//位组转换成字节组函数
2、调试
3、运行结果
4、存盘
参考程序:
DES源程序
///
///DES加密
///
///被加密的明文
///密钥
///向量
///密文
publicstaticByte[]DESEncrypt(Byte[]Data,StringKey,StringVector)
{
Byte[]bKey=newByte[8];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)),bKey,bKey.Length);
Byte[]bVector=newByte[8];
Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)),bVector,bVector.Length);
Byte[]Cryptograph=null;//加密后的密文
DESCryptoServiceProviderEncryptProvider=newDESCryptoServiceProvider();
EncryptProvider.Mode=CipherMode.CBC;
EncryptProvider.Padding=PaddingMode.Zeros;
try
{
//开辟一块内存流
using(MemoryStreamMemory=newMemoryStream())
{
//把内存流对象包装成加密流对象
using(CryptoStreamEncryptor=newCryptoStream(Memory,
EncryptProvider.CreateEncryptor(bKey,bVector),
CryptoStreamMode.Write))
{
//明文数据写入加密流
Encryptor.Write(Data,0,Data.Length);
Encryptor.FlushFinalBlock();
Cryptograph=Memory.ToArray();
}
}
}
catch
{
Cryptograph=null;
}
returnCryptograph;
}
///
///DES解密
///
///被解密的密文
///密钥
///向量
///明文
publicstaticByte[]DESDecrypt(Byte[]Data,StringKey,StringVector)
{
Byte[]bKey=newByte[8];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)),bKey,bKey.Length);
Byte[]bVector=newByte[8];
Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)),bVector,bVector.Length);
Byte[]original=null;
DESCryptoServiceProviderCryptoProvider=newDESCryptoServiceProvider();
CryptoProvider.Mode=CipherMode.CBC;
CryptoProvider.Padding=PaddingMode.Zeros;
try
{
//开辟一块内存流,存储密文
using(MemoryStreamMemory=newMemoryStream(Data))
{
//把内存流对象包装成加密流对象
using(CryptoStreamDecryptor=newCryptoStream(Memory,
CryptoProvider.CreateDecryptor(bKey,bVector),
CryptoStreamMode.Read))
{
//明文存储区
using(MemoryStreamoriginalMemory=newMemoryStream())
{
Byte[]Buffer=newByte[1024];
Int32readBytes=0;
while((readBytes=Decryptor.Read(Buffer,0,Buffer.Length))>0)
{
originalMemory.Write(Buffer,0,readBytes);
}
original=originalMemory.ToArray();
}
}
}
}
catch
{
original=null;
}
returnoriginal;
}
实验结果
加密:
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算法的验证类实验,需要按实验报告模板的表格填写,具体要求如下:
(1)实验总结须反映实验步骤中的结果,并提供文字描述。
(2)除教师评语外,实验报告表中的每项内容均由本实验的同学填写。
(3)实验总结和实验自我评语,严禁雷同。
(4)实验报告需要按实验报告模板的格式进行填写。
实验四:
RSA加解密算法的实现(4学时)
一、实验目的
通过本实验的学习,使学生掌握RSA加密算法的加解密过程,培养学生的编程能力和对算法的理解,加深对公钥密码算法的了解,为今后继续哈希函数的学习奠定基础。
二、实验内容
实现RSA加解密算法。
三、实验原理、方法和手段
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。
用下面这个公式他可以将m加密为c:
c=m^e(modn)
计算c并不复杂。
Bob算出c后就可以将它传递给Alice。
3、解密消息
Alice得到Bob的消息c后就可以利用她的密钥d来解码。
她可以用以下这个公式来将c转换为m:
m=c^d(modn)
她可以将原来的信息m重新复原。
四、实验环境、条件
运行Windows7操作系统的PC机,具有C语言、C++编译环境。
五、实验组织运行要求
根据本实验的特点、要求和具体条件,采用以学生自主训练为主的开放模式组织教学,每个学生按照实验指导书,独立完成实验。
六、实验步骤
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源程序
#include
#include
#include
#include
#include
usingnamespacestd;
//存放素数
intprime[1305];
//用筛选法求素数
intp[10005];
voidPRIME()
{
inti,i2,k;
for(i=0;i<=10000;i+=2)
p[i]=0;
for(i=1;i<=10000;i+=2)
p[i]=1;
p[2]=1;p[1]=0;
for(i=3;i<=100;i+=2)
{
if(p[i]==1)
{
i2=i+i;
k=i2+i;
while(k<=10000)
{
p[k]=0;
k+=i2;
}
}
}
prime[0]=1;
prime[1]=2;
for(i=3;i<=10000;i+=2)
if(p[i])
prime[++prime[0]]=i;
}
//计算逆元素
__int64mod(__int64a,__int64n)
{
return(a%n+n)%n;
}
voidgcd(__int64a,__int64b,__int64&d,__int64&x,__int64&y)
{
if(b==0)
{
d=a;
x=1;
y=0;
return;
}
gcd(b,a%b,d,y,x);
y-=x*(a/b);
}
//a-1modn
__int64Inv(__int64a,__int64n)//计算逆元素
{
__i