现代密码学实验报告.docx
《现代密码学实验报告.docx》由会员分享,可在线阅读,更多相关《现代密码学实验报告.docx(22页珍藏版)》请在冰点文库上搜索。
现代密码学实验报告
现代密码学
实验报告
学生姓名
学号
专业班级
指导教师
学院
完成时间
实验一对称密码算法实验
[实验目的]
1.掌握密码学中经典的对称密码算法DES、AES、RC4的算法原理。
2.掌握DES、AES、RC4的算法流程和实现方法。
[实验内容]
1.分析DES、AES、RC4、SHA的实现过程。
2.用程序设计语言将算法过程编程实现。
3.完成字符串数据的加密运算和解密运算
输入明文:
Idolikethisbook
输入密钥:
cryption
[实验步骤]
一、DES算法
1、DES算法及原理
DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。
明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
2、DES算法加解密过程
(1)DES算法加密过程如下:
a.初始置换。
DES的第一阶段包括64位分组的置换,改变每个分组中位的顺序。
术语置换使用其严格的数学意义;只改变了顺序。
这64位数据现在被分成两半:
L0(左半部分)和R0(右半部分)。
下标0说明是原始的数据。
在DES算法第二阶段的每次循环后,这些下标加1。
b.循环移位(16次)
一种根据密钥,并且依赖于表格的算法。
这种操作通常被称为数据移位。
这个算法要重复16次,但由于每次移位都使用密钥的不同子分组,因此每次移位的操作各不相同。
密钥的子分组由另一组表格和表格的移位算法来确定。
在每次循环以后,L(左半部分)和R(右半部分)的下标依次加一。
第16次循环的结果被称为预输出。
c.逆置换
DES的最后一个阶段包括64位分组的置换,改变每个分组中位的顺序,这与第1阶段的操作类似。
这次置换的输出结果就是密文。
(2)解密过程
DES的解密过程和加密过程相同,只是在解密过程中将子密钥的使用顺序颠倒。
3、DES算法的java实现
DES算法流程图
关键代码:
1)初始化秘钥数组
。
privatevoidKeyInitialize(int[]key,int[][]keyarray){
inti;
intj;
int[]K0=newint[56];
//特别注意:
xxx[IP[i]-1]等类似变换
for(i=0;i<56;i++){
K0[i]=key[PC_1[i]-1];//密钥进行PC-1变换
}
for(i=0;i<16;i++){
LeftBitMove(K0,LeftMove[i]);
//特别注意:
xxx[IP[i]-1]等类似变换
for(j=0;j<48;j++){
keyarray[i][j]=K0[PC_2[j]-1];//生成子密钥keyarray[i][j]
}
}
2)执行加密解密操作
privatebyte[]Encrypt(int[]timeData,intflag,int[][]keyarray){
inti;
byte[]encrypt=newbyte[8];
intflags=flag;
int[]M=newint[64];
int[]MIP_1=newint[64];
//特别注意:
xxx[IP[i]-1]等类似变换
for(i=0;i<64;i++){
M[i]=timeData[IP[i]-1];//明文IP变换
}
if(flags==1){//加密
for(i=0;i<16;i++){
LoopF(M,i,flags,keyarray);
}
}elseif(flags==0){//解密
for(i=15;i>-1;i--){
LoopF(M,i,flags,keyarray);
}
}
for(i=0;i<64;i++){
MIP_1[i]=M[IP_1[i]-1];//进行IP-1运算
}
GetEncryptResultOfByteArray(MIP_1,encrypt);
//返回加密数据
returnencrypt;
}
3)循环以为操作函数
privatevoidLeftBitMove(int[]k,intoffset){
inti;
int[]c0=newint[28];
int[]d0=newint[28];
int[]c1=newint[28];
int[]d1=newint[28];
for(i=0;i<28;i++){
c0[i]=k[i];
d0[i]=k[i+28];
}
if(offset==1){
for(i=0;i<27;i++){//循环左移一位
c1[i]=c0[i+1];
d1[i]=d0[i+1];
}
c1[27]=c0[0];
d1[27]=d0[0];
}elseif(offset==2){
for(i=0;i<26;i++){//循环左移两位
c1[i]=c0[i+2];
d1[i]=d0[i+2];
}
c1[26]=c0[0];
d1[26]=d0[0];
c1[27]=c0[1];
d1[27]=d0[1];
}
for(i=0;i<28;i++){
k[i]=c1[i];
k[i+28]=d1[i];
}
}
运行结果:
二.AES算法
1、AES算法及原理
AES加密算法即密码学中的高级加密标准(AdvancedEncryptionStandard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
AES设计有三个密钥长度:
128,192,256位,相对而言,AES的128密钥比DES的56密钥强1021倍。
AES算法主要包括三个方面:
轮变化、圈数和密钥扩展。
AES是分组密钥,算法输入128位数据,密钥长度也是128位。
用Nr表示对一个数据分组加密的轮数(加密轮数与密钥长度的关系如表1所列)。
每一轮都需要一个与输入分组具有相同长度的扩展密钥Expandedkey(i)的参与。
由于外部输入的加密密钥K长度有限,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥K扩展成更长的比特串,以生成各轮的加密和解密密钥。
2.AES算法加密解密过程
3、AES算法java实现
1)加密
publicstaticbyte[]encrypt(Stringcontent,StringkeyWord){
try{
KeyGeneratorkgen=KeyGenerator.getInstance("AES");
SecureRandomsecureRandom=SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(keyWord.getBytes());
kgen.init(128,secureRandom);
SecretKeysecretKey=kgen.generateKey();
byte[]enCodeFormat=secretKey.getEncoded();
SecretKeySpeckey=newSecretKeySpec(enCodeFormat,"AES");
Ciphercipher=Cipher.getInstance("AES");//创建密码器
byte[]byteContent=content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE,key);//初始化
byte[]result=cipher.doFinal(byteContent);
returnresult;//加密
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(UnsupportedEncodingExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}
returnnull;
}
2)解密
publicstaticbyte[]decrypt(byte[]content,StringkeyWord){
try{
KeyGeneratorkgen=KeyGenerator.getInstance("AES");
SecureRandomsecureRandom=SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(keyWord.getBytes());
kgen.init(128,secureRandom);
SecretKeysecretKey=kgen.generateKey();
byte[]enCodeFormat=secretKey.getEncoded();
SecretKeySpeckey=newSecretKeySpec(enCodeFormat,"AES");
Ciphercipher=Cipher.getInstance("AES");//创建密码器
cipher.init(Cipher.DECRYPT_MODE,key);//初始化
byte[]result=cipher.doFinal(content);
returnresult;//加密
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}catch(NoSuchPaddingExceptione){
e.printStackTrace();
}catch(InvalidKeyExceptione){
e.printStackTrace();
}catch(IllegalBlockSizeExceptione){
e.printStackTrace();
}catch(BadPaddingExceptione){
e.printStackTrace();
}
returnnull;
}
3)二进制转化为十六进制
publicstaticStringparseByte2HexStr(bytebuf[]){
StringBuffersb=newStringBuffer();
for(inti=0;iStringhex=Integer.toHexString(buf[i]&0xFF);
if(hex.length()==1){
hex='0'+hex;
}
sb.append(hex.toUpperCase());
}
returnsb.toString();
}
4)测试代码
publicstaticvoidmain(String[]args){
Stringcontent="Idolikethisbook";
StringKey="cryption";
//加密
System.out.println("加密前:
"+content);
StringencryptResult=encrypttoStr(content,Key);
System.out.println("加密后:
"+encryptResult);
//解密
byte[]decryptResult=decrypt(encryptResult,Key);
System.out.println("解密后:
"+newString(decryptResult));
}
}
运行结果
三、RC4算法
1.RC4算法及原理
RC4加密算法是大名鼎鼎的RSA三人组中的头号人物RonRivest在1987年设计的密钥长度可变的流加密算法簇。
之所以称其为簇,是由于其核心部分的S-box长度可为任意,但一般为256字节。
该算法的速度可以达到DES加密的10倍左右。
RC4算法的原理很简单,包括初始化算法和伪随机子密码生成算法两大部分。
2.RC4算法加密解密过程
加密流程:
1.1加密表的初始化(设加密表的长度为256,事实上加密表的长度可以任意,只是在实现时256可以用一个字节表示索引)
|-----------------------------------------|
|初始化SecurityBox(Sbox)|---->|------------------------------------|
|(设为0~255即可,算法上没有||fori=0,255=>Sbox[i]=i|
|要求,只要和解密表一致就可以)||------------------------------------|
|-----------------------------------------|
|
|-----------------------------------------||-----------------------------------------------|
|通过key来扰乱Sbox,key可以是任|---->|m=n=0,extend(key,256)|
|意相量好的字符序列,它最长是||fori=0,256|
|和Sbox的长度一样,如果它比Sbox||m=(m+Sbox[i]+key[n+1])%256|
|长度少,那么重复使用||Swap(Sbox[i],Sbox[m])|
|-----------------------------------------||n=(n+1)%256|
|-----------------------------------------------|
1.2加密字节
|--------------------------------------------||-----------------------------------------------|
|在Sbox中查找加密字节,并修改|---->|i,j=(Sbox.idx_i+1)%256,Sbox.idx_j|
|Sbox的值||j=(Sbox[i]+j)%256|
|--------------------------------------------||code=s[(Sbox[i]+Sbox[j])%256]|
||Swap(Sbox[i],Sbox[j])|
||Sbox.idx_i,Sbox.idx_j=i,j|
||returncode|
||------------------------------------------------|
|
|----------------------------------||----------------------------------------|
|加密对应的输入字节|---->|out_byte=in_byteXORcode|
|----------------------------------||-----------------------------------------|
解密表的初始化过程和解密的过程完全一样,也就是说按照上面的算法生成两份表Table1和Table2,那么
input_byte=crypt(crypt(input_byte,Table1),Table2)-->input_byteXORs_codeXORs_code=input_byte
3.RC4算法java实现
1)加解密
publicclassTestFindAndFugai{
publicstaticStringHloveyRC4(StringaInput,StringaKey){
int[]iS=newint[256];
byte[]iK=newbyte[256];
for(inti=0;i<256;i++)
iS[i]=i;
intj=1;
for(shorti=0;i<256;i++){
iK[i]=(byte)aKey.charAt((i%aKey.length()));
}
j=0;
for(inti=0;i<255;i++){
j=(j+iS[i]+iK[i])%256;
inttemp=iS[i];
iS[i]=iS[j];
iS[j]=temp;
}
inti=0;
j=0;
char[]iInputChar=aInput.toCharArray();
char[]iOutputChar=newchar[iInputChar.length];
for(shortx=0;xi=(i+1)%256;
j=(j+iS[i])%256;
inttemp=iS[i];
iS[i]=iS[j];
iS[j]=temp;
intt=(iS[i]+(iS[j]%256))%256;
intiY=iS[t];
chariCY=(char)iY;
iOutputChar[x]=(char)(iInputChar[x]^iCY);
}
returnnewString(iOutputChar);
}
2)测试
publicstaticvoidmain(String[]args){
StringinputStr="Idolikethisbook";
Stringkey="cryption";
Stringstr=HloveyRC4(inputStr,key);
//打印加密后的字符串
System.out.println("加密后:
"+str);
//打印解密后的字符串
System.out.println("解密后:
"+HloveyRC4(str,key));
}
运行结果
实验二公钥密码算法实验
[实验目的]
1.掌握密码学中常用的公钥密码算法RSA、ECC的算法原理。
2.掌握RSA、ECC的算法流程和实现方法。
[实验内容]
1.分析RSA、ECC的实现过程。
2.用程序设计语言将算法过程编程实现
3.完成数据的加密运算和解密运算
输入明文:
security
输入密钥:
cryption
对ASCII码进行加密和解密。
[实验步骤]
1.RSA算法及原理
RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名。
RSA以它的三个发明者RonRivest,AdiShamir,LeonardAdleman的名字首字母命名,这个算法经受住了多年深入的密码分析,虽然密码分析者既不能证明也不能否定RSA的安全性,但这恰恰说明该算法有一定的可信性,目前它已经成为最流行的公开密钥算法。
RSA的安全基于大数分解的难度。
其公钥和私钥是一对大素数(100到200位十进制数或更大)的函数。
从一个公钥和密文恢复出明文的难度,等价于分解两个大素数之积(这是公认的数学难题)。
RSA的公钥、私钥的组成,以及加密、解密的公式可见于下表:
2.RSA算法加密解密过程
(1)选择一对不同的、足够大的素数p和q。
(2)计算n=pq。
(3)计算f(n)=(p-1)(q-1),同时对p和q严加保密,不让任何人知道。
(4)找一个与f(n)互质的数e,且1(5)计算d,使得demodf(n)≡1modf(n)。
这个公式也可以表达为d≡e-1modf(n)
这里要解释一下,≡是数论中表示同余的符号。
公式中,≡符号的左边必须和符号右边同余,也就是两边模运算结果相同。
显而易见,不管f(n)取什么值,符号右边1modf(n)的结果都等于1;符号的左边d与e的乘积做模运算后的结果也必须等于1。
这就需要计算出d的值,让这个同余等式能够成立。
(6)公钥KU=(e,n),私钥KR=(d,n)。
(7)加密时,先将明文变换成0至n-1的一个整数M。
若明文较长,可先分割成适当的组,然后再进行交换。
设密文为C,则加密过程为:
C≡Me(modn)
(8)解密过程为:
M≡Cd(modn)
3.RSA算法java实现
1)加密
publicbyte[]encrypt(Keykey,byte[]data)throwsException{
try{
Ciphercipher=Cipher.getInstance("RSA",new
org.bouncycastle.jce.provider.BouncyCastle