注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。1上海电力学院实验报告课程名称信息安全/计算机安全实验项目实验一DES数据加密算法姓名张三学号班级专业电子信息工程同组人姓名指导教师姓名魏为民实验日期2011年月日一、实验目的通过本实验的学习,深刻理解DES加密标准,提高算法设计能力,为今后继续学习密码技术和数字签名奠定基础。二、实验内容根据DES加密标准,用C++设计编写符合DES算法思想的加、解密程序,能够实现对字符串和数组的加密和解密。三、实验步骤1.在操作系统环境下启动VC++集成环境(MicrosoftVisualC++6.0,其中6.0为版本号,也可为其它版本),则产生如图1所示界面。图1VC++集成环境界面2.选择“文件”菜单下的“新建”命令,出现如图2所示界面(不可直接按“新建”按钮,此按钮是新建一个文本文件)。此界面缺省标签是要为新程序设定工程项目,但编辑小的源程序也可以不建立项目,可以直接选择其左上角的“文件”标签,产生如图3所示界面。3.在图3所示的界面中左边选定文件类型为“C++SourceFile”,右边填好文件名并选定文件存放目录,注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。2然后单击“确定”按钮,出现如图4所示编程界面,开始输入程序。4.输入完源程序后,按编译菜单下的编译命令,对源程序进行编译。系统将在下方的窗口中显示编译信息。如果无此窗口,可按Alt+2键或执行查看菜单下的输出命令。如果编译后已无提示错误,则可按编译菜单下的构件命令来生成相应的可执行文件,随后可按编译菜单下的执行命令运行的程序。图2新建VC++工程项目界面图3新建VC++源程序文件界面注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。3图4VC++源程序编辑界面四、DES算法的过程1.处理密钥:1.1从用户处获得64位密钥Key。(每第8位为校验位,为使密钥有正确的奇偶校验,每个字节要有奇数个“1”位。1.2处理过程:1.2.1对密钥实施变换,经过子密钥换位表PC-1的变换后,Key的位数由64位变成了56位。1.2.2把变换后的密钥等分成两部分,前28位记为C0,后28位记为D0。1.2.3计算子密钥(共16个),从i=1开始。1.2.3.1分别对Ci-1、Di-1作循环左移来生成Ci、Di(共16次)。1.2.3.2串联Ci、Di,得到一个56位数,然后对此数作子密钥换位表PC-2变换以产生48位子密钥Ki。1.2.3.3按以上方法计算出16个子密钥。2.对64位数据块的处理:2.1把数据分成64位的数据块,不够64位的以适当方式填补。2.2对数据块利用初始变换IP表作变换。2.3将变换后的数据块等分成前后两部分,前32位记为L0,后32位记为R0。2.4用16个子密钥对数据加密。2.4.1利用扩展置换E,将32位R(i-1)数据扩展成48位。2.4.2用E{R(i-1)}与子密钥K(i)作按位异或运算。2.4.3把所得的48位数分成8个6位数组。1-6位为Z1,7-12位为Z2,……43-48位为Z8。2.4.4从j=1开始,用S盒里的值替换Zj。S盒里的值为4位数,共8个S盒,输出32位数。2.4.4.1取出Zj的第1和第6位串联起来成一个2位数,记为m。m即是Sj盒里用来替换Zj的数所在的行数。2.4.4.2取出Zj的第2至第5位串联起来成一个4位数,记为n。n即是Sj盒里用来替换Zj的数所在的列数。2.4.4.3用坐标(m,n)在S盒中查找出相应的值作为S盒的输出。2.4.5八个选择函数Sj(1≤j≤8)的输出拼接为32位二进制数据,把它作为P盒置换的输入,得到输出注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。42.4.6把得到的结果与L(i-1)作异或运算。把计算结果賦给R(i)。2.4.7把R(i-1)的值賦给L(i),完成1轮乘积变换。2.4.8从2.4.1起循环执行16次,直到K(16)也被用到。2.5把R(16)和L(16)顺序串联起来得到一个64位数。对这个数实施2.2变换的逆变换IP-1。五.算法实现(1)源程序:#ifndef_DES_ENCRYPT_DECRYPT#define_DES_ENCRYPT_DECRYPT#defineBYTEunsignedchar#defineLPBYTEBYTE*#defineLPCBYTEconstBYTE*#defineBOOLintclassDES{public:BOOLCDesEnter(LPCBYTEin,LPBYTEout,intdatalen,constBYTEkey[8],BOOLtype);BOOLCDesMac(LPCBYTEmac_data,LPBYTEmac_code,intdatalen,constBYTEkey[8]);private:voidXOR(constBYTEin1[8],constBYTEin2[8],BYTEout[8]);LPBYTEBin2ASCII(constBYTEbyte[64],BYTEbit[8]);LPBYTEASCII2Bin(constBYTEbit[8],BYTEbyte[64]);voidGenSubKey(constBYTEoldkey[8],BYTEnewkey[16][8]);voidendes(constBYTEm_bit[8],constBYTEk_bit[8],BYTEe_bit[8]);voidundes(constBYTEm_bit[8],constBYTEk_bit[8],BYTEe_bit[8]);voidSReplace(BYTEs_bit[8]);};/**CDesEnter函数说明:*des加密/解密入口*返回:*1则成功,0失败*参数:*in需要加密或解密的数据*注意:in缓冲区的大小必须和datalen相同.*out加密后或解密后输出。*注意:out缓冲区大小必须是8的倍数而且比datalen大或者相等。*如datalen=7,out缓冲区的大小应该是8,datalen=8,out缓冲区的大小应该是8,*datalen=9,out缓冲区的大小应该是16,依此类推。*datalen数据长度(字节)。*注意:datalen必须是8的倍数。*key8个字节的加密或解密的密码。*type是对数据进行加密还是解密注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。5*0表示加密1表示解密*/BOOLDES::CDesEnter(LPCBYTEin,LPBYTEout,intdatalen,constBYTEkey[8],BOOLtype){//判断输入参数是否正确,失败的情况为://!in:in指针(输入缓冲)无效//!out:out指针(输出缓冲)无效//datalen1:数据长度不正确//!key:加/解密密码无效//type&&((datalen%8)!=0:选择解密方式但是输入密文不为8的倍数if((!in)||(!out)||(datalen1)||(!key)||(type&&((datalen%8)!=0)))returnfalse;if(type==0)//选择的模式是加密{//用于存储待加密字串最后的若干字节//DES算法是以8个字节为单位进行加密,如果待加密字串以8为单位分段加密时,最后一段不足//8字节,则在后面补0,使其最后一段的长度为8字节//te8bit是作为存储待加密字串最后一段(不足8字节)的变量BYTEte8bit[8]={0,0,0,0,0,0,0,0};//这是待加密字串的调整长度//如果原始长度是8的整数倍,则调整长度的值和原来的长度一样//如果原始长度不是8的整数倍,则调整长度的值是能被8整除且不大于原来长度的最大整数。//也就是不需要补齐的块的总长度intte_fixlen=datalen-(datalen%8);//将待加密密文以8为单位分段,把最后长度不足8的一段存储到te8bit中for(inti=0;i(datalen%8);i++)te8bit[i]=in[te_fixlen+i];//将待加密字串分以8字节为单位分段加密for(i=0;ite_fixlen;i+=8)endes(in+i,key,out+i);//如果待加密字串不是8的整数倍,则将最后一段补齐(补0)后加密if(datalen%8!=0)endes(te8bit,key,out+datalen/8*8);}else//选择的模式是解密{//将密文以8字节为单位分段解密for(inti=0;idatalen;i+=8)undes(in+i,key,out+i);}注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。6returntrue;}/**CDesMAC函数说明:*DESMAC数据验校*返回:*1则成功,0失败*参数:*mac_dataMAC验校数据*注意:Mac_data缓冲区的大小(16字节以上)必须和datalen相同,而且应是8的倍数。*out_macMAC验校输出(8字节)*dadalen数据长度(字节)。*注意:datalen必须是16以上而且是8的倍数。*key8个字节的验校密码。*/BOOLDES::CDesMac(LPCBYTEmac_data,LPBYTEmac_code,intdatalen,constBYTEkey[8]){//判断输入参数是否正确,失败的情况为://!mac_data:mac_data指针(输入缓冲)无效//!mac_code:mac_code指针(输出缓冲)无效//datalen16:数据长度不正确//datalen%8!=0:数据长度不为8的整数倍//!key:密码不符合要求if((!mac_data)||(!mac_code)||(datalen16)||(datalen%8!=0)||(!key))returnfalse;endes(mac_data,key,mac_code);for(inti=8;idatalen;i+=8){XOR(mac_code,mac_data+i,mac_code);endes(mac_code,key,mac_code);}returntrue;}/**XOR函数说明:*将输入的两个8字节字符串异或*返回:*无*参数:*constBYTEin1[8]输入字符串1*constBYTEin2[8]输入字符串2*BYTEout[8]输出的结果字符串*/voidDES::XOR(constBYTEin1[8],constBYTEin2[8],BYTEout[8])注:实验报告内容包括:实验目的与要求、实验原理与内容、实验步骤与记录、实验分析与结论等。7{for(inti=0;i8;i++)out[i]=in1[i]^in2[i];}/**Bin2ASCII函数说明:*将64字节的01字符串转换成对应的8个字节*返回:*转换后结果的指针*参数:*constBYTEbyte[64]输入字符串*BYTEbit[8]输出的转换结果*/LPBYTEDES::Bin2ASCII(constBYTEbyte[64],BYTEbit[8]){for(inti=0;i8;i++){bit[i]=byte[i*8]*128+byte[i*8+1]*64+byte[i*8+2]*32+byte[i*8+3]*16+byte[i*8+4]*8+byte[i*8+5]*4+byte[i*8+6]*2+byte[i*8+7];}returnbit;}/**ASCII2Bin函数说明:*将8个字节输入转换成对应的64字节的01字符串*返回:*转换后结果的指针*参数:*constBYTEbit[8]输入字符串*BYTEbyte[64]输出的转换结果