3DES加密解密的实现.docx

上传人:b****8 文档编号:9673948 上传时间:2023-05-20 格式:DOCX 页数:25 大小:398.38KB
下载 相关 举报
3DES加密解密的实现.docx_第1页
第1页 / 共25页
3DES加密解密的实现.docx_第2页
第2页 / 共25页
3DES加密解密的实现.docx_第3页
第3页 / 共25页
3DES加密解密的实现.docx_第4页
第4页 / 共25页
3DES加密解密的实现.docx_第5页
第5页 / 共25页
3DES加密解密的实现.docx_第6页
第6页 / 共25页
3DES加密解密的实现.docx_第7页
第7页 / 共25页
3DES加密解密的实现.docx_第8页
第8页 / 共25页
3DES加密解密的实现.docx_第9页
第9页 / 共25页
3DES加密解密的实现.docx_第10页
第10页 / 共25页
3DES加密解密的实现.docx_第11页
第11页 / 共25页
3DES加密解密的实现.docx_第12页
第12页 / 共25页
3DES加密解密的实现.docx_第13页
第13页 / 共25页
3DES加密解密的实现.docx_第14页
第14页 / 共25页
3DES加密解密的实现.docx_第15页
第15页 / 共25页
3DES加密解密的实现.docx_第16页
第16页 / 共25页
3DES加密解密的实现.docx_第17页
第17页 / 共25页
3DES加密解密的实现.docx_第18页
第18页 / 共25页
3DES加密解密的实现.docx_第19页
第19页 / 共25页
3DES加密解密的实现.docx_第20页
第20页 / 共25页
亲,该文档总共25页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

3DES加密解密的实现.docx

《3DES加密解密的实现.docx》由会员分享,可在线阅读,更多相关《3DES加密解密的实现.docx(25页珍藏版)》请在冰点文库上搜索。

3DES加密解密的实现.docx

3DES加密解密的实现

目录

1.背景与意义4

2.系统设计4

2.1系统主要目标4

2.2主要软件需求(运行环境)5

2.3功能模块与系统结构5

3系统功能程序设计6

3.1基本要求部分6

3.1.1相关格式转换函数6

3.1.2生成子密钥7

3.1.3DES中的轮结构10

IP逆置换11

E盒扩展11

P盒置换12

S盒置换13

左右交换14

3.1.4DES加密单个分组14

3.1.5DES解密单个分组16

3.1.63DES加密单个分组17

3.1.73DES解密单个分组17

3.2程序界面预览18

4.测试报告21

5.结论21

参考文献21

1.背景与意义

通过《应用密码学》这门课程学习了理论上的DES的加密和解密算法以后,通过C++类的思想和VC++图形界面的展示,通过实践实现基本的DES算法以及3DES(EDE2)。

并且通过此类派生出来的其他类,也可以再今后的场合中,包括IM软件,都可以调用此类来进行功能的扩展。

所以说DES核心算法的实现,是相当有意义的。

本程序主要实现了3DES(EDE2)基本的文本加密。

文本加密可以是8位以内的字符。

 

2.系统设计

2.1系统主要目标

基本要求部分:

根据题目要求完成了哪些内容,具体的列举出来

1.在深入理解DES加密/解密算法理论的基础上,设计一个3DES(EDE2模式)加密/解密软件系统;

2.完成一个明文分组的加解密,明文和密钥是ASCII码,且都从文本文件读取。

3.进行加密时,要求输出每次调用DES算法后的值,即加密一组明文输出两组中间值和一组密文,且能够进行正确的解密,输出同加密;

4.要求提供所设计系统的报告及完整的软件;

5.提供良好的用户界面。

较高要求部分:

1.如果明文不止一个分组,程序能完成分组,然后加密;密钥长度不足时能进行填充,过长是自动截取前面部分。

2.要求明文输入是文本文档,以及任意文件,且长度不止一个分组。

进行加密后,能够进行正确的解密;

3.程序代码有比较好的结构,如用类进行封装,通过调用类的成员函数实现加密解密功能等;

4.对加密大文件的考虑;

5.多线程的使用。

2.2主要软件需求(运行环境)

本软件适用VC语言编写,编译成功后的EXE文件可以在装有windows系统的任何计算机上使用。

测试平台:

Windows7(64)

使用软件:

VisualStudio2008

 

2.3功能模块与系统结构

本程序由于时间比较紧凑,自己写的函数没有封装到类里,以后有时间会继续完善代码。

以上是我本人写的18个函数,对于功能模块的进行了比较良好的划分。

CDESDlg是一个MFC自动生成的类。

其主要功能是实现了连接界面和内部核心代码之间的桥梁。

3系统功能程序设计

3.1基本要求部分

3.1.1相关格式转换函数

概述:

在MFC编程中,对于编辑框内容的获取,与文件的操作使用char型数据都是比较方便的,考虑到如此,过程中会有许多相互转化的函数。

因此我先把我用到的转换函数列出。

intByteToBit(charch,charbit[8])

{

inti;

for(i=0;i<8;i++)

{

*(bit+(7-i))=(ch>>i)&1;

}

return0;

}

函数解释:

例如字符为’c’,ascii码为99,八位二进制为01100011,首先bit[0]的值是ch右移0位并与1,得1,bit[1]的值是ch右移1位并与1,得1,以此类推得到八位字符串11000110,在进行倒置得到目的字符的二进制形式。

 

intChar8ToBit64(charch[8],charbit[64])

{

inti;

for(i=0;i<8;i++)

{

ByteToBit(*(ch+i),bit+(i<<3));

}

return0;

}

函数解释:

0左移3为变为0,1左移3位变为8,2变16,3变24,4变32,5变40,6变48,7变56;

调用ByteToBit将每个字符的二进制按顺序赋给各个bit数组。

 

intBit64ToChar8(charbit[64],charch[8])

{

inti,j=0,k=0;

charbit1[8][8];

for(i=0;i<8;i++)

{

ch[i]=0;

}

for(i=0;i<64;i++)

{

bit1[j][k]=bit[i];

k++;

if((i+1)%8==0)

{

j+=1;

k=0;

}

}

for(i=0;i<8;i++)

{

for(j=0;j<8;j++)

{

ch[i]+=bit1[i][j]*pow(2.0,(7-j));

}

}

return0;

}

}

函数解释:

将64位的2进制变成8位的字符串,从bit[64]中读取,存放在ch[8]中。

3.1.2生成子密钥

概述:

子密钥产生过程的输入,为用户持有的64比特初始密钥,经过选择置换PC-1(permuted

Choice1),得到56bit,接着分为2个28bit分组,在进行一个循环左移位,再按PC-2进行压缩,得到子密钥。

intDES_MakeSubKeys(charkey[64],charsubKeys[16][48])//subKeys[16][48]存储每一轮的密钥

{

chartemp[56];//临时存储

inti;

DES_PC1_Transform(key,temp);//PC_1,将key[64]转到temp[56]里存放

for(i=0;i<16;i++)

{

DES_ROL(temp,Move_Left[i]);//循环移位

DES_PC2_Transform(temp,subKeys[i]);//PC_2

}

return0;

}

函数解释:

输入初始密钥,产生16轮的子密钥,存放在subKeys[16][48]这个二维数组里,调用了DES_PC1_Transform(charkey[64],chartempbts[56]),DES_PC2_Transform(charkey[56],char*tempbts),DES_ROL(chardata[56],inttime)三个函数

 

intDES_PC1_Transform(charkey[64],chartempbts[56])//key[64]密钥,经过PC_1置换后存放在tempbts[56]中

{

inti;

for(i=0;i<56;i++)

{

tempbts[i]=key[PC_1[i]-1];

}

return0;

}

函数解释:

从key[64]中读取数据,经过PC_1置换后存放在tempbts[56]中

代码:

intDES_PC2_Transform(charkey[56],char*tempbts)//同上

{

inti;

for(i=0;i<48;i++)

{

tempbts[i]=key[PC_2[i]-1];

}

return0;

}

函数解释:

查PC-2表,置换密钥中的值

 

intDES_ROL(chardata[56],inttime)

{

inti;

//chartemp[56];

chardeposit[2];//存放要循环的数

switch(time)

{

case1:

//左移位为1时

deposit[0]=data[0];//前28位的左移位

for(i=1;i<28;i++)

{

data[i-1]=data[i];

}

data[27]=deposit[0];

deposit[0]=data[28];//后28位的左移位

for(i=29;i<56;i++)

{

data[i-1]=data[i];

}

data[55]=deposit[0];

break;

case2:

//左移位为2时

deposit[0]=data[0];//前28位

deposit[1]=data[1];

for(i=2;i<28;i++)

{

data[i-2]=data[i];

}

data[26]=deposit[0];

data[27]=deposit[1];

deposit[0]=data[28];//后28位,temp[28]-temp[55]

deposit[1]=data[29];

for(i=30;i<56;i++)

{

data[i-2]=data[i];

}

data[54]=deposit[0];

data[55]=deposit[1];

break;

}

return0;

}

函数解释:

这里用了一个switch语句,判断time传递进来的是1还是2,然后申明了一个deposit数组来存放要移位的数。

3.1.3DES中的轮结构

IP置换:

 

intDES_IP_Transform(chardata[64])

{

inti;

chartemp[64];

for(i=0;i<64;i++)

{

temp[i]=data[IP_CHANGE_Table[i]-1];

}

memcpy(data,temp,64);

return0;

}

函数解释:

从数组data[64]中读取数据,进行查表操作IP置换。

IP逆置换

intDES_IP_1_Transform(chardata[64])

{

inti;

chartemp[64];

for(i=0;i<64;i++)

{

temp[i]=data[IP_BACK_Table[i]-1];

}

memcpy(data,temp,64);

return0;

}

函数解释:

查IP_BACK_Table表,进行IP逆置换操作

E盒扩展

 

intDES_E_Transform(chardata[48])

{

inti;

chartemp[48];

for(i=0;i<48;i++)

{

temp[i]=data[E_Table[i]-1];

}

memcpy(data,temp,48);

return0;

}

函数解释:

查E_Table表,进行E盒扩展操作

异或

 

intDES_XOR(charR[48],charL[48],intcount)

{

inti;

for(i=0;i

{

R[i]^=L[i];

}

return0;

}

函数解释:

输入要异或的数目,左右数组逐个进行异或操作。

存放在R的数组里。

P盒置换

 

 

intDES_P_Transform(chardata[32])

{

inti;

chartemp[32];

for(i=0;i<32;i++)

{

temp[i]=data[P_Table[i]-1];

}

memcpy(data,temp,32);

return0;

}

函数解释:

通过查找P_Table表完成P盒置换操作

S盒置换

intDES_SBOX(chardata[48])

{

chartemp[8][6];

charrowtemp[2];//用数组存放行的头尾两个数字

charlinetemp[4];//存放中间的4个数字

inti,i1=3,j,k=0;

introw,line;

intmedian;

for(i=0;i<8;i++)

{

for(j=0;j<6;j++)

{

temp[i][j]=data[k];

k++;

}

}

for(i=0;i<8;i++)

{

rowtemp[1]=temp[i][0];

rowtemp[0]=temp[i][5];

row=int(rowtemp[1]*pow(2.0,1)+rowtemp[0]*pow(2.0,0));//转10进制

linetemp[0]=temp[i][4];

linetemp[1]=temp[i][3];

linetemp[2]=temp[i][2];

linetemp[3]=temp[i][1];

line=int(linetemp[0]*pow(2.0,0)+linetemp[1]*pow(2.0,1)+linetemp[2]*pow(2.0,2)+linetemp[3]*pow(2.0,3));//转10进制

median=S_Table[i][row][line];

//转2进制(从后面开始向前存储)

for(j=0;j<4;j++)

{

data[i1-j]=median%2;

median=median/2;

}

i1=i1+4;

}

return0;

}

函数解释:

将输入的48位数组的每6位进行分组,第1*2加上第6位为对应的行号,中间四位分别乘8,4,2,1的加和为对应的列号,进行查表置换得到ascii值,例如i=0,查s盒第一个表,行号keyXORri_1[0]*2+keyXORri_1[5],列号为keyXORri_1[1])*8+(keyXORri_1[2])*4+(keyXORri_1[3])*2+keyXORri_1[4]]

左右交换

intDES_Swap(charleft[32],charright[32])

{

chartemp[32];

memcpy(temp,left,32);

memcpy(left,right,32);

memcpy(right,temp,32);

return0;

}

函数解释:

通过memcpy这个系统函数来进行左右交换操作。

3.1.4DES加密单个分组

函数名:

DES_EncryptBlock

参数:

(charplainBlock[9],charsubKeys[16][48],charcipherBits[64])

 

结论:

实现了加密单个分组的功能

代码:

intDES_EncryptBlock(charplainBlock[9],charsubKeys[16][48],charcipherBits[64])

{

charplainBits[64]={0};

charcopyRight[48]={0};

inti;

//转进制

Char8ToBit64(plainBlock,plainBits);

//IP置换

DES_IP_Transform(plainBits);

for(i=0;i<16;i++)

{

//实现右半边操作

memcpy(copyRight,plainBits+32,32);

//E盒扩充(输出位)

DES_E_Transform(copyRight);

//右半边和每一轮子密钥异或(输出位)

DES_XOR(copyRight,subKeys[i],48);

//S盒置换(输出位)

DES_SBOX(copyRight);

//P盒置换(输出位)

DES_P_Transform(copyRight);

//右边和左边进行异或(存放在plainBits)

DES_XOR(plainBits,copyRight,32);

//第轮不交换

if(i!

=15)

{

DES_Swap(plainBits,plainBits+32);

}

}

//IP逆置换

DES_IP_1_Transform(plainBits);

memcpy(cipherBits,plainBits,64);

return0;

}

 

3.1.5DES解密单个分组

函数名:

DES_DecryptBlock

参数:

(charcipherBits[64],charsubKeys[16][48],charplainBlock[9])

 

结论:

实现了解密单个分组的功能

代码:

 

intDES_DecryptBlock(charcipherBits[64],charsubKeys[16][48],charplainBlock[9])

{

inti;

charcopyRight[48]={0};

//IP置换

DES_IP_Transform(cipherBits);

for(i=15;i>=0;i--)

{

//实现右半边操作

memcpy(copyRight,cipherBits+32,32);

//E盒扩充(输出位)

DES_E_Transform(copyRight);

//右半边和每一轮子密钥异或(输出位)

DES_XOR(copyRight,subKeys[i],48);

//S盒置换(输出位)

DES_SBOX(copyRight);

//P盒置换(输出位)

DES_P_Transform(copyRight);

//右边和左边进行异或(存放在plainBits)

DES_XOR(cipherBits,copyRight,32);

//第轮不交换

if(i!

=0)

{

DES_Swap(cipherBits,cipherBits+32);

}

}

//IP逆置换

DES_IP_1_Transform(cipherBits);

Bit64ToChar8(cipherBits,plainBlock);

return0;

}

 

3.1.63DES加密单个分组

函数名:

DES_EncryptBlock3

参数:

(charplainBlock[9],charsubKeys1[16][48],charsubKeys2[16][48],charcipherBits[64])

结论:

实现了3DES(EDE2)模式加密单个分组的功能

代码:

intDES_EncryptBlock3(charplainBlock[9],charsubKeys1[16][48],charsubKeys2[16][48],charcipherBits[64])

{

//key1加密

DES_EncryptBlock(plainBlock,subKeys1,cipherBits);

//key2解密

DES_DecryptBlock(cipherBits,subKeys2,plainBlock);

//key1加密

DES_EncryptBlock(plainBlock,subKeys1,cipherBits);

return0;

}

 

3.1.73DES解密单个分组

函数名:

DES_DecryptBlock3

参数:

(charcipherBits[64],charsubKeys1[16][48],charsubKeys2[16][48],charplainBlock[9])

结论:

实现了3DES(EDE2)模式解密单个分组的功能

代码:

intDES_DecryptBlock3(charcipherBits[64],charsubKeys1[16][48],charsubKeys2[16][48],charplainBlock[9])

{

//key1解密

DES_DecryptBlock(cipherBits,subKeys1,plainBlock);

//key2加密

DES_EncryptBlock(plainBlock,subKeys2,cipherBits);

//key1解密

DES_DecryptBlock(cipherBits,subKeys1,plainBlock);

return0;

}

3.2程序界面预览

说明……………………

从文件中读出数据:

点击浏览可以选择读取文件

输出时要选择输出模式,有两种,分别是二进制输出和字符串输出,

这是二进制输出:

这是解密二进制输出:

这是解密:

4.测试报告

本程序经过测试,文本加密,任意字符,只要是电脑能显示出来的字符都能加密,而且轮密钥显示正常,也能解密回原来的结果。

但是由于没有做较高要求,所以只能加密和解密一个分组长度的字符。

5.结论

DES加密虽然已经过时了,但是通过本程序写的类的扩展性非常好,可以通过这个DESCORE核心代码扩展出很多DES的不同算法,当然也可以适用于不同加密模式。

本程序的内核结构非常清晰,但是由于时间原因,在服务类的设计上还有所欠缺。

我也学会了灵活使用MSDN查阅各种API和各种函数的用法。

通过进一步分析DES算法的特性,同时也对数据在内存中的存储有了更进一步的认识。

对MFC的windows编程有了进一步的认识。

但是由于基础还不够扎实,在写代码的时候也会遇到很多基础问题。

所以通过这次课程设计,使我明白了凡是都要把基础打牢固了,才能有更进一步的发展,基础不稳,知识面再广,也只是空中楼阁。

今后,我相信我还会再改写一遍3DES在这次的基础上会完善代码。

参考文献

[1]JeffreyRichter,ChristopheNasarre.Windows核心编程(第五版)[M]清华大学出版社 2008

[2]StanleyB.Lippman,JoseeLajoie,BarbrarE.Moo.C++Primer(第四版)[M]人民邮电出版社(第四版) 2006

[3]张仕斌,万武南,张金全,孙宣东.应用密码学[M]西安电子科技大学出版社2009

[4]王艳萍,张铮.Windows程序设计(第二版)[M]人民邮电出版社 2008

[5]孙鑫,余安萍.VC++深入详解[M]电子工业出版社2006

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 化学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2