1、 一实验目的通过用DES算法对实际的数据进行加密和解密来深刻了解DES的运行原理。二实验软件环境运行Windows或Linux操作系统的PC机,具有gcc(Linux)、VC(Windows)等C语言编译环境。三实验内容1.算法分析根据所提供的程序分析DES算法的实现过程。DES程序包括一个头文件和一个实现DES算法的C文件。头文件里主要是一些宏定义和函数声明,其中还包括保证可移植性的一些定义。DES程序通过宏定义可选择小代码模式(#define small code)或者选择大代码模式。在大代码模式下,程序定义了多个表,从而使DES算法中的很多运算都可以通过查表实现,速度较快,但要求有较多的
2、存储空间;在小代码模式运行时,可以不查表,从而节省了存储空间,但是速度较慢。读者可以根据自己的需求来选择不同的运行模式。加密解密时主要用到下面5个函数。(l)int des_setup(const unsigned char *key,int keylen,int num_rounds,des_key *skey)函数名称:密钥生成函数。参数说明:key是一个指针,指向用户输入的初始密钥。keylen是输入密钥的长度,以字节为单位。num_rounds是加密轮数,当输入0时,使用算法默认的轮数。skey是一个指向结构体变量的指针,变量里面存储加密和解密时每轮使用的子密钥。当密钥生成时,返回值为
3、CRYPT_OK(0),结果保留在Skey指向的结构体。des_key的定义如下:typedef struct des_keyulong32 ek32, dk32;des_key结构体里的ek存储加密时用的子密钥,dk存储解密时用的子密钥。结构体中用2个32位的整数来存储一轮的48位密钥,每一个32位整数被分成4个8位,每个8位的第6位存储密钥。如果把48位密钥分成8组,则这8组按存储的顺序从高到低分别为1、3、5、7、2、4、6、8。这样做是为了加密时可以把扩展和查表运算结合起来。(2)void des_ecb_encrypt(const unsigned char *pt, unsigne
4、d char *ct, des_key *key)函数名称:加密函数。参数说明;pt是指向待加密的明文数组的指针。ct是指向存储加密结果的指针。key是调用密钥生成函数后存储每一轮子密钥的结构体变量。加密成功时,返回CRYPT_OK。(3)void des_ecb_decrypt(const unsigned char *ct,unsigned char *pt,des_key *key)函数名称:解密函数。参数说明:ct是指向待解密的密文数组的指针。pt是指向存储解密结果的指针。key是调用密钥生成函数后存储每一轮子密钥的结构体变量。解密成功时,返回CRYPT_OK。加密和解密时,pt和ct
5、可以指向同一块内存。(4)int des_test(void)函数名称:测试函数。这个函数用来对加密算法进行测试。函数体内部定义了对应的明文和密文数组,并且进行了多轮加密和解密。这个函数还可以用来测试函数的运行时间。(5)nit des_keysize(int *desired_keysize)函数名称:密钥长度检验函数。参数说明:desired_keysize是使用者所想要的密钥长度。当密钥长度小于所需密钥长度时,返回值为CRYPT_INVALID_KEYSIZE,否则,desired_keysize指向的变量被置为 8。2 使用实例分析#include des.hint main(int
6、argc, char *argv)unsigned char pt9=abcdefg,ct9,key8= a,b,c,d,a,b,c,d ;des_key skey;pt9l=ct9=0;des_setup(key,8,0,&skey);des_ecb_encrypt(pt.ct,&skey);des_ecb_decrypt(ct.pt,&skey);printf(%sn,pt);prinif(%sn,ct);system(PAUSE);retun 0;说明:这个程序演示了对一组8Byte的数据进行加密和解密的过程。pt指向明文数组,ct指向密文数组,skey是密钥数组。pt和ct数组长度设为
7、9,是为了方便控制台字符串输出。对文件加密时,可以指定读取和写入的字符数,这两个数组长度应该定义为8。四、实验结果:(1)使用附录提供的程序对一个文件进行加密和解密,提交程序代码和执行结果。修改程序,添加main函数,使程序能够正常运行,并作修改如下:int main(int argc, char *argv)int choice; system(color f0); coutendl; cout选项: endl; cout1.文件加密 2.文件解密 endl; coutendl; coutchoice; coutendl; if(choice=1) char a;char ifn10;cha
8、r ofn10;/文件名cout输入需要加密的文件名:ifn;cout输入加密后想要的文件名:ofn;ifstream f1(ifn); /从文件中读出ofstream f2(ofn); /写到到文件中unsigned char pt9,ct9,nt50,mt9,key8= a,b,c,d,a,b,c,d ;symmetric_key skey;int n=0;int nn=0;while(!f1.eof()a=f1.get();ntn=a;n+;ntn=0;for(int count=0;count=(n-1)/8;count+)mt8=0;ct8=0;pt8=0;for(int i=0;i
9、8;i+)pti=ntnn;nn+;des_setup(key,8,0,&skey);des_ecb_encrypt(pt,ct,&skey);for(int m=0;m8;m+)f2.put(ctm);cout加密完成!endl;f1.close() ;f2.close() ;system(PAUSE); else if(choice=2) char a;char ifn10;char ofn10;/文件名cout输入需要解密的文件名:ifn;cout输入解密后想要的文件名:ofn;ifstream f1(ifn); /从文件中读出ofstream f2(ofn); /写到到文件中unsig
10、ned char pt9,ct9,nt50,mt9,key8= a,b,c,d,a,b,c,d ;symmetric_key skey;int n=0;int nn=0;while(!f1.eof()a=f1.get();ntn=a;n+;ntn=0;for(int count=1;count=(n-1)/8;count+)mt8=0;ct8=0;pt8=0;for(int i=0;i8;i+)cti=ntnn;nn+;ct8=0;des_setup(key,8,0,&skey); des_ecb_decrypt(ct,pt,&skey);for(int m=0;m8;m+)if(ptm=25
11、5) break;f2.put(ptm);cout解密完成!endl;f1.close() ;f2.close() ; else if(choice=3) unsigned char pt50=i love c,ct50,mt50,key8= a,b,c,d,a,b,c,d ;symmetric_key skey;pt8=ct8=0;mt8=0;des_setup(key,8,0,&skey);des_ecb_encrypt(pt,ct,&skey);printf(%sn,pt);printf(%sn,ct); des_ecb_decrypt(ct,mt,&skey); printf(%sn,
12、ct);printf(%sn,mt); else cout输入错误!;return 0; 运行结果:初始文件:123.txt对123.txt进行加密加密后文件:321.txt再对经过加密的文件321.txt解密解密后文件:111.txt(2)使用附录提供的程序对输入的十六进制数加密(把输入的字符转化成整数。例如,输入两个字符1F,转化成二进制数000lllll),比较输入和输出。当把输入的数改变一个位时(如把1F变为1E),比较输出的变化,并说明原因。程序修改如下:int main( )/生成密钥unsigned char key 8 = a,b,c,d,a,b,c,d ;des_key sk
13、ey;des_setup( key, 8, 0, &skey );cout n加密前输入原文:;string bufferString1;void inputData( string &input );inputData( bufferString1 );/加密数据string bufferString2;void encodeHexadecimal( string &input, string &output, des_key &skey );encodeHexadecimal( bufferString1, bufferString2, skey );/输出加密数据cout n加密后输出密
14、文:;void outputData( string &output );outputData( bufferString2 );/解密数据void decodeHexadecimal( string &input, string &output, des_key &skey );decodeHexadecimal( bufferString2, bufferString1, skey );/输出解密数据cout n解密后输出原文:;outputData( bufferString1 );return 0;/输入 16 进制数据,转换为按字节存储的字符串,即待加密的数据void inputDa
15、ta( string &input )for ( char tempChar1= cin.get( ); tempChar1 != 10; tempChar1= cin.get( ) )char ascToHexadecimal( char asc );tempChar1= ascToHexadecimal( tempChar1 ) 4;char tempChar2= cin.get( );if ( tempChar2 = 10 )tempChar2= 48;input+= ascToHexadecimal( tempChar2 ) + tempChar1;return;input+= asc
16、ToHexadecimal( tempChar2 ) + tempChar1;/将需要输出的数据转换为 16 进制数并输出void outputData( string &output )for ( int i= 0; i output.length( ); i+ )char hexadecimalToAsc( char hexadecimal );cout 4 & 0x0f );cout hexadecimalToAsc( output i & 0x0f );cout endl;/用 DES 算法加密 input 中的数据,存放在 output 中void encodeHexadecimal
17、( string &input, string &output, des_key &skey )for ( int i= 0; i input.length( ); i+= 8 )char bufferChar1 9 , bufferChar2 9 ;for ( int j= 0; j 8; j+ )if ( i + j input.length( ) )bufferChar1 j = input i + j ;elsebufferChar1 j = 0;bufferChar2 j = 0;bufferChar1 8 = bufferChar2 8 = 0;des_ecb_encrypt( (
18、unsigned char *)bufferChar1, (unsigned char *)bufferChar2, &skey );for ( j= 0; j 8 & bufferChar2 j ; j+ )output+= bufferChar2 j ;/用 DES 算法解密 input 中的数据,存放在 output 中void decodeHexadecimal( string &input, string &output, des_key &skey )output= ;for ( int i= 0; i input.length( ); i+= 8 )char bufferChar
19、1 9 , bufferChar2 9 ;for ( int j= 0; j 8; j+ )if ( i + j input.length( ) )bufferChar1 j = input i + j ;elsebufferChar1 j = 0;bufferChar2 j = 0;bufferChar1 8 = bufferChar2 8 = 0;des_ecb_decrypt( (unsigned char *)bufferChar1, (unsigned char *)bufferChar2, &skey );for ( j= 0; j 8 & bufferChar2 j ; j+ )output+= bufferChar2 j ;/把 16 进制数字转换为 ASCII 码字符并返回char hexadecimalToAsc( char hexadecimal )if ( hexadecimal = 97 )return asc - 87;if ( asc = 65 )return asc - 55;return asc - 48;运行结果:输入二进制数1F和1E:五实验心得体会通过分析DES算法的实现过程的实验,深刻了解了数据据加密解密的整个流程,了解了DES的运行原理,懂得如何通过编程实现数据的DES加密及其效率的比较。word文档可自由复制编辑