密码学实验报告.docx
《密码学实验报告.docx》由会员分享,可在线阅读,更多相关《密码学实验报告.docx(41页珍藏版)》请在冰豆网上搜索。
密码学实验报告
(此文档为word格式,下载后您可任意编辑修改!
)
《—现代密码学—》
实验指导书
适用专业:
计算机科学与技术
江苏科技大学计算机科学学院
2011年11月
实验一古典密码
实验学时:
2学时
实验类型:
验证
实验要求:
必修
一、实验目的
编程实现古典密码的加解密方法。
二、实验内容
(1)移位密码的加密和解密函数。
(2)仿射密码的加密和解密函数。
(3)维吉尼亚密码的加密和解密函数。
三、实验原理、方法和手段
(1)移位密码
对于明文字符,加密密钥,加密方法为
解密方法为
(2)仿射密码
(3)维吉尼亚密码
选取密钥字Key,将明文按照密钥字长度分组,将明文与密钥字对应字符相加并对26求余,即为密文字符。
解密过程为
四、实验组织运行要求
本实验采用集中授课形式,每个同学独立完成上述实验要求。
五、实验条件
每人一台计算机独立完成实验,有如下条件:
(1)硬件:
微机;
(2)软件:
VC++6.0、VC++.Net2005。
六、实验步骤
(1)将各函数编写完成;
(2)在主函数中调用各函数,实现加密和解密。
七、实验报告
实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。
移位密码加密:
#includevoidchange(charstring[]){inti;for(i=0;string[i]!='\0';i++){if(string[i]>='a'&&string[i]<='z')string[i]=(string[i]+n>='z'?string[i]+n-26:string[i]+n);}}voidmain(){charstr[100];printf("请输入一段明文");gets(str);change(str);printf("密文为:\n");puts(str);}移位密码解密:#includevoidchange(charstring[]){inti;for(i=0;string[i]!='\0';i++){if(string[i]>='a'&&string[i]<='z')string[i]=(string[i]+n<'a'?string[i]-n+26:string[i]-n);}}voidmain(){charstr[100];printf("请输入一段密文");gets(str);change(str);printf("明文为:\n");puts(str);}仿射密码加密:#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("明文:%s\n",string);fun(string,x,y);printf("密文为:%s\n",string);}仿射密码解密:#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("密文:%s\n",string);fun(string,x,y);printf("明文:%s\n",string);}密码加密:#includefor(i=t;i<(5-t%5)+t;i++)将一维数组old每5个分成一组不足5位的用X补充old[i]='x';for(i=t+(5-t%5);i<100;i++)old[i]='\0';for(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][0]=temp[i][1];new1[i][1]=temp[i][4];new1[i][2]=temp[i][3];new1[i][3]=temp[i][0];new1[i][4]=temp[i][2];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}密码解密#includefor(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][1]=temp[i][0];new1[i][4]=temp[i][1];new1[i][3]=temp[i][2];new1[i][0]=temp[i][3];new1[i][2]=temp[i][4];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}实验二序列密码实验学时:2学时实验类型:验证实验要求:必修一、实验目的编程实现序列密码RC4的加密方法。二、实验内容序列密码RC4。三、实验原理、方法和手段RC4首先进行S表的初始化:(1);(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。(3)J=0;(4)对于I=0到255,重复以下步骤①;②交换和。RC4对下面(1)~(5)循环后,得出密钥流的一个字节z。(1);(2)(3)(4)交换和;(5);(6).四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。线性移位寄存器:#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
voidchange(charstring[])
{
inti;
for(i=0;string[i]!
='\0';i++)
if(string[i]>='a'&&string[i]<='z')
string[i]=(string[i]+n>='z'?
string[i]+n-26:
string[i]+n);
}
voidmain()
charstr[100];
printf("请输入一段明文");
gets(str);
change(str);
printf("密文为:
\n");
puts(str);
移位密码解密:
#includevoidchange(charstring[]){inti;for(i=0;string[i]!='\0';i++){if(string[i]>='a'&&string[i]<='z')string[i]=(string[i]+n<'a'?string[i]-n+26:string[i]-n);}}voidmain(){charstr[100];printf("请输入一段密文");gets(str);change(str);printf("明文为:\n");puts(str);}仿射密码加密:#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("明文:%s\n",string);fun(string,x,y);printf("密文为:%s\n",string);}仿射密码解密:#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("密文:%s\n",string);fun(string,x,y);printf("明文:%s\n",string);}密码加密:#includefor(i=t;i<(5-t%5)+t;i++)将一维数组old每5个分成一组不足5位的用X补充old[i]='x';for(i=t+(5-t%5);i<100;i++)old[i]='\0';for(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][0]=temp[i][1];new1[i][1]=temp[i][4];new1[i][2]=temp[i][3];new1[i][3]=temp[i][0];new1[i][4]=temp[i][2];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}密码解密#includefor(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][1]=temp[i][0];new1[i][4]=temp[i][1];new1[i][3]=temp[i][2];new1[i][0]=temp[i][3];new1[i][2]=temp[i][4];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}实验二序列密码实验学时:2学时实验类型:验证实验要求:必修一、实验目的编程实现序列密码RC4的加密方法。二、实验内容序列密码RC4。三、实验原理、方法和手段RC4首先进行S表的初始化:(1);(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。(3)J=0;(4)对于I=0到255,重复以下步骤①;②交换和。RC4对下面(1)~(5)循环后,得出密钥流的一个字节z。(1);(2)(3)(4)交换和;(5);(6).四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。线性移位寄存器:#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
string[i]=(string[i]+n<'a'?
string[i]-n+26:
string[i]-n);
printf("请输入一段密文");
printf("明文为:
仿射密码加密:
#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("明文:%s\n",string);fun(string,x,y);printf("密文为:%s\n",string);}仿射密码解密:#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("密文:%s\n",string);fun(string,x,y);printf("明文:%s\n",string);}密码加密:#includefor(i=t;i<(5-t%5)+t;i++)将一维数组old每5个分成一组不足5位的用X补充old[i]='x';for(i=t+(5-t%5);i<100;i++)old[i]='\0';for(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][0]=temp[i][1];new1[i][1]=temp[i][4];new1[i][2]=temp[i][3];new1[i][3]=temp[i][0];new1[i][4]=temp[i][2];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}密码解密#includefor(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][1]=temp[i][0];new1[i][4]=temp[i][1];new1[i][3]=temp[i][2];new1[i][0]=temp[i][3];new1[i][2]=temp[i][4];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}实验二序列密码实验学时:2学时实验类型:验证实验要求:必修一、实验目的编程实现序列密码RC4的加密方法。二、实验内容序列密码RC4。三、实验原理、方法和手段RC4首先进行S表的初始化:(1);(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。(3)J=0;(4)对于I=0到255,重复以下步骤①;②交换和。RC4对下面(1)~(5)循环后,得出密钥流的一个字节z。(1);(2)(3)(4)交换和;(5);(6).四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。线性移位寄存器:#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
for(i=0;a[i]!
a[i]=(x*(a[i]-97)+y)%26+97;
main()
charstring[100];
intx,y;
printf("输入");
gets(string);
printf("请输入密钥");
scanf("%d,%d",&x,&y);
printf("明文:
%s\n",string);
fun(string,x,y);
仿射密码解密:
#include{inti;for(i=0;a[i]!='\0';i++){a[i]=(x*(a[i]-97)+y)%26+97;}}main(){charstring[100];intx,y;printf("输入");gets(string);printf("请输入密钥");scanf("%d,%d",&x,&y);printf("密文:%s\n",string);fun(string,x,y);printf("明文:%s\n",string);}密码加密:#includefor(i=t;i<(5-t%5)+t;i++)将一维数组old每5个分成一组不足5位的用X补充old[i]='x';for(i=t+(5-t%5);i<100;i++)old[i]='\0';for(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][0]=temp[i][1];new1[i][1]=temp[i][4];new1[i][2]=temp[i][3];new1[i][3]=temp[i][0];new1[i][4]=temp[i][2];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}密码解密#includefor(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][1]=temp[i][0];new1[i][4]=temp[i][1];new1[i][3]=temp[i][2];new1[i][0]=temp[i][3];new1[i][2]=temp[i][4];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}实验二序列密码实验学时:2学时实验类型:验证实验要求:必修一、实验目的编程实现序列密码RC4的加密方法。二、实验内容序列密码RC4。三、实验原理、方法和手段RC4首先进行S表的初始化:(1);(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。(3)J=0;(4)对于I=0到255,重复以下步骤①;②交换和。RC4对下面(1)~(5)循环后,得出密钥流的一个字节z。(1);(2)(3)(4)交换和;(5);(6).四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。线性移位寄存器:#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
printf("密文:
密码加密:
#includefor(i=t;i<(5-t%5)+t;i++)将一维数组old每5个分成一组不足5位的用X补充old[i]='x';for(i=t+(5-t%5);i<100;i++)old[i]='\0';for(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][0]=temp[i][1];new1[i][1]=temp[i][4];new1[i][2]=temp[i][3];new1[i][3]=temp[i][0];new1[i][4]=temp[i][2];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}密码解密#includefor(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][1]=temp[i][0];new1[i][4]=temp[i][1];new1[i][3]=temp[i][2];new1[i][0]=temp[i][3];new1[i][2]=temp[i][4];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}实验二序列密码实验学时:2学时实验类型:验证实验要求:必修一、实验目的编程实现序列密码RC4的加密方法。二、实验内容序列密码RC4。三、实验原理、方法和手段RC4首先进行S表的初始化:(1);(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。(3)J=0;(4)对于I=0到255,重复以下步骤①;②交换和。RC4对下面(1)~(5)循环后,得出密钥流的一个字节z。(1);(2)(3)(4)交换和;(5);(6).四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。线性移位寄存器:#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
for(i=t;i<(5-t%5)+t;i++)将一维数组old每5个分成一组不足5位的用X补充
old[i]='x';
for(i=t+(5-t%5);i<100;i++)
old[i]='\0';
for(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组temp
for(j=0;j<5;j++)
temp[i][j]=old[5*i+j];
for(i=0;i<20;i++)密文字母交换顺序
new1[i][0]=temp[i][1];
new1[i][1]=temp[i][4];
new1[i][2]=temp[i][3];
new1[i][3]=temp[i][0];
new1[i][4]=temp[i][2];
charold[100],new1[20][5];
gets(old);
change(old,new1);
printf("%s",new1);
密码解密
#includefor(i=0;i<20;i++)将一维数组old转换成一个20*5的二维数组tempfor(j=0;j<5;j++)temp[i][j]=old[5*i+j];for(i=0;i<20;i++)密文字母交换顺序{new1[i][1]=temp[i][0];new1[i][4]=temp[i][1];new1[i][3]=temp[i][2];new1[i][0]=temp[i][3];new1[i][2]=temp[i][4];}}main(){charold[100],new1[20][5];gets(old);change(old,new1);printf("%s",new1);}实验二序列密码实验学时:2学时实验类型:验证实验要求:必修一、实验目的编程实现序列密码RC4的加密方法。二、实验内容序列密码RC4。三、实验原理、方法和手段RC4首先进行S表的初始化:(1);(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。(3)J=0;(4)对于I=0到255,重复以下步骤①;②交换和。RC4对下面(1)~(5)循环后,得出密钥流的一个字节z。(1);(2)(3)(4)交换和;(5);(6).四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。线性移位寄存器:#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
new1[i][1]=temp[i][0];
new1[i][4]=temp[i][1];
new1[i][3]=temp[i][2];
new1[i][0]=temp[i][3];
new1[i][2]=temp[i][4];
实验二序列密码
编程实现序列密码RC4的加密方法。
序列密码RC4。
RC4首先进行S表的初始化:
(1);
(2)用密钥填充另一个256字节的数组K,如果密钥长度小于256字节,则依次重复填充,直至填满这个数组。
(3)J=0;
(4)对于I=0到255,重复以下步骤
①;
②交换和。
RC4对下面
(1)~(5)循环后,得出密钥流的一个字节z。
(2)
(3)
(4)交换和;
(5);
(6).
线性移位寄存器:
#include{inti,j;charans;while(1){printf("\n***************************************************************\n\n");printf("PleaseinputtheInitKey:\n");输入四个字符作为初始密钥,老师要求:goodfor(i=0;i<4;i++)scanf("%c",&InputKey[i]);KeyToBit();printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):\n");输入需要加密的明文,以#作为结束符for(i=0;i<1000;i++){scanf("%c",&Info[i]);记录输入的明文tempInfo[i]=Info[i];将Ascii值同步附给tempInfoif(Info[i]=='#'){InfoLength=i;break;遇到#则停止读取}}printf("\n***************************************************************\n\n");printf("TheCipheris:\n");for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
inti,j;
charans;
while
(1)
printf("\n***************************************************************\n\n");
printf("PleaseinputtheInitKey:
\n");输入四个字符作为初始密钥,老师要求:
good
for(i=0;i<4;i++)
scanf("%c",&InputKey[i]);
KeyToBit();
printf("\nPleaseinputtheInformationencrypted(Endwith\"#\"):
\n");输入需要加密的明文,以#作为结束符
for(i=0;i<1000;i++)
scanf("%c",&Info[i]);记录输入的明文
tempInfo[i]=Info[i];将Ascii值同步附给tempInfo
if(Info[i]=='#')
InfoLength=i;
break;遇到#则停止读取
printf("TheCipheris:
for(i=0,j=0;i{InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]LFSR();加密Cipher[j]=Out[0];printf("%c",Cipher[j]);Cipher[j+1]=Out[1];printf("%c",Cipher[j+1]);j=j+2;}printf("\n***************************************************************\n\n");printf("Continue?yn?\n");getchar();消除前面输入的字符对本次输入的影响scanf("%c",&ans);getchar();if(ans=='n')按n不继续测试break;}}voidKeyToBit(){inti,j,r;for(i=0;i<4;i++){r=InputKey[i];for(j=0;j<8;j++)Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。j=7;while(r!=0)十进制转化为二进制的普遍算法{Bit[j--]=r%2;r=r2;}for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位InitKey[8*i+j]=Bit[j];}}---voidLFSR(){intp,q,temp;p=0;while(p<8){temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];抽头序列的异或值保存在tempfor(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间InitKey[q]=InitKey[q-1];InitKey[0]=temp;InitKey[0]保存抽头序列的异或值LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密p++;}for(p=0;p<8;p++)Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果Output16();得到的8位0、1序列转化为16进制输出}---voidOutput16(){inti,j,TextInt,OutInt[2];TextInt=0;OutInt[0]=0;OutInt[1]=0;for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中TextInt=TextInt+Bit[i]*(int)pow(2,7-i);j=1;while(1)十进制转化为十六进制(整数表示){OutInt[j]=TextInt%16;TextInt=TextInt16;j--;if(j<0)break;}for(i=0;i<2;i++)字符表示{if(OutInt[i]>9)Out[i]=OutInt[i]-10+'A';elseOut[i]=OutInt[i]+'0';}}---voidInfoToBit(intj){intTextInt,i;TextInt=Info[j];i=0;for(i=0;i<8;i++)Bit[i]=0;i=7;while(TextInt!=0){Bit[i]=TextInt%2;TextInt=TextInt2;i--;}}实验三DES实验学时:4学时实验类型:验证实验要求:必修一、实验目的编程实现分组密码DES的加解密方法。二、实验内容分组密码DES。三、实验原理、方法和手段DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。对,施行和,同样的过程得,,如此循环16次,最后得,。再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。运算过程可用公式(3.1)简洁地表示如下:i=1,2,…16.(3.1)注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。以上是对DES加解密过程得描述。我们把从到的变换过程称为一轮加密。初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。图3-1DES加解密流程IP58,50,42,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,726,5,图3-2初始置换IP及逆初始置换的计算过程如下:讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。其中在第i轮为。可用图3-3表示。13,16,17,20,21,24,25,28,29,32,1, EP图3-3扩展运算E与置换P其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。图3-4f函数运算框图每个S-盒是有6个输入,4个输出地变换,其变换规则为:取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。密钥方案的计算:子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。其中需要注意的是:置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。图3-5子密钥的产生过程对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。四、实验组织运行要求本实验采用集中授课形式,每个同学独立完成上述实验要求。五、实验条件每人一台计算机独立完成实验,有如下条件:(1)硬件:微机;(2)软件:VC++6.0、VC++.Net2005。六、实验步骤(1)将各函数编写完成;(2)在主函数中调用各函数,实现加密和解密。七、实验报告实验报告主要包括实验目的、实验内容、实验原理、源程序及结果。#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
InfoToBit(i);每个明文字符单独转化为8bit位序列,保存到Bit[8]
LFSR();加密
Cipher[j]=Out[0];
printf("%c",Cipher[j]);
Cipher[j+1]=Out[1];
printf("%c",Cipher[j+1]);
j=j+2;
printf("Continue?
yn?
getchar();消除前面输入的字符对本次输入的影响
scanf("%c",&ans);
getchar();
if(ans=='n')按n不继续测试
break;
voidKeyToBit()
inti,j,r;
r=InputKey[i];
for(j=0;j<8;j++)
Bit[j]=0;每个密钥序列初始化为全0,避免上一次转化保存到Bit数组给本次转化的影响。
j=7;
while(r!
=0)十进制转化为二进制的普遍算法
Bit[j--]=r%2;
r=r2;
for(j=1;j<=8;j++)将本次转化得到的8位序列附给初始化密钥序列InitKey相应的位
InitKey[8*i+j]=Bit[j];
---
voidLFSR()
intp,q,temp;
p=0;
while(p<8)
temp=InitKey[31]^InitKey[6]^InitKey[4]^InitKey[2]^InitKey[1]^InitKey[0];
抽头序列的异或值保存在temp
for(q=31;q>0;q--)将InitKey的元素后移,空出第0个的空间
InitKey[q]=InitKey[q-1];
InitKey[0]=temp;InitKey[0]保存抽头序列的异或值
LFSRKey[p]=InitKey[31];这个就是每一次要求的LFSR序列,8个保存一次,便于加密
p++;
for(p=0;p<8;p++)
Bit[p]=Bit[p]^LFSRKey[p];当前明文字符的位序列与当前得到的LFSR异或得到加密结果
Output16();得到的8位0、1序列转化为16进制输出
voidOutput16()
inti,j,TextInt,OutInt[2];
TextInt=0;
OutInt[0]=0;
OutInt[1]=0;
for(i=0;i<8;i++)先把二进制转化为十进制整数保存在TextInt中
TextInt=TextInt+Bit[i]*(int)pow(2,7-i);
j=1;
(1)十进制转化为十六进制(整数表示)
OutInt[j]=TextInt%16;
TextInt=TextInt16;
j--;
if(j<0)
for(i=0;i<2;i++)字符表示
if(OutInt[i]>9)
Out[i]=OutInt[i]-10+'A';
else
Out[i]=OutInt[i]+'0';
voidInfoToBit(intj)
intTextInt,i;
TextInt=Info[j];
i=0;
for(i=0;i<8;i++)
Bit[i]=0;
i=7;
while(TextInt!
=0)
Bit[i]=TextInt%2;
TextInt=TextInt2;
i--;
实验三DES
4学时
编程实现分组密码DES的加解密方法。
分组密码DES。
DES是对二元数字分组加密的分组密码算法,分组长度为64比特。
每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第为奇偶检验位,所以,实际密钥只有56位。
DES算法完全公开,其保密性完全依赖密钥。
图3-1是DES全部16轮的加解密结构图,其最上方的64比特输入分组数据,可能是明文,也可能是密文,视使用者要做加密或解密而定。
而加密与解密的不同处,仅在于最右边的16个子密钥的使用顺序不同,加密的子密钥顺序为,而解密的子密钥顺序正好相反,为。
DES算法首先对输入的64位明文X进行一次初始置换IP(见图3-2),以打乱原来的次序。
对置换侯的数据分成左右两半,左边记为,右边记为,对施行在子密钥控制下的变换,其结果记为,得到的32比特输出再与做逐位异或(XOR)运算,其结果成为下一轮的,则成为下一轮的。
对,施行和,同样的过程得,,如此循环16次,最后得,。
再对64位数字,施行初始置换的逆置换(见图3-2),既得密文Y。
运算过程可用公式(3.1)简洁地表示如下:
i=1,2,…16.(3.1)
注意,在16次加密后并未交换,,而直接将,作为的输入,这样做使得DES的解密和加密完全相同,在以上过程中只需输入密文并反序输入子密钥,最后获得的就是相应的明文。
以上是对DES加解密过程得描述。
我们把从到的变换过程称为一轮加密。
初始置换IP及其逆置换并没有密码学意义,因为X与IP(X)(或Y与(Y))的一一对应关系是已知的,如X德第58比特是IP(X)的第1比特,X的第50比特是IP(X)的第2比特等等。
他们的作用在于打乱原来输入X的ASC2码字划分的关系,并将原来明文的第位(校验位)变成IP的输出地一个字节。
函数是整个DES加密法中最重要的部分,而其中的重点又在S-盒(SubstitutionBoxes)上。
函数可记作,其中A为32位输入,J为48位输入,在第i轮,,为由初始密钥(亦称种子密钥)导出的第i轮子密钥,输出为32比特。
图3-1DES加解密流程
IP
58,50,42,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
26,
5,
图3-2初始置换IP及逆初始置换
的计算过程如下:
讲A经过一个选择扩展运算E(见图3-3)变为48位,记为E(A)。
计算,对B施行代换S,此代换由8个代换盒组成,就是前面说过的S-盒。
每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记,其中Bj作为第j个S-盒的输入,的输出为,就是代换S的输出,所以代换S是一个48位输入,32位输出选择压缩运算,讲结果C再施行一个置换P(见图3-3),既得。
其中在第i轮为。
可用图3-3表示。
13,
16,17,
20,21,
24,25,
28,29,
32,1,
EP
图3-3扩展运算E与置换P
其中,扩展运算E与置换P主要作用是增加算法的扩散效果,具体运算如图3-4所示。
S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。
它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。
有些人甚至还大胆猜测,是否设计者故意在S-盒的设计上留下了一些陷门(Trapdoor),以便他们能轻易地破解出别人的密文,当然以上的臆测是否属实,迄今仍无法得知,不过有一点可以确定,那就是S-盒的设计的确相当神秘。
图3-4f函数运算框图
每个S-盒是有6个输入,4个输出地变换,其变换规则为:
取{0,1,…..,15}上的4个置换,即它的4个排列排成4行,得以4*16矩阵。
若给定该S-盒的输入,其输出对应该矩阵第L行n列所对应的数的二进制表示。
这里L的二进制表示为,n的二级制表示为,这样,每个S-盒可用一个4*16矩阵或数来表示。
密钥方案的计算:
子密钥产生过程(图3-5)中的输入,为使用者所持有的64比特初始密钥。
在加密或解密时,使用者先将初始密钥输入至子密钥产生流程中即可。
首先经过密钥置换PC-1,讲初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。
接着并分两路为两个28比特的分组及,再分别经过一个循环左移函数,得到与,连成56比特数据,再依据密钥置换PC-2做重排动作便可输出子密钥,而至的产生方法,以此类推。
其中需要注意的是:
置换PC-1的输入为64比特,输出为56比特;而密钥置换PC-2的输入和输出分别为56和48比特。
图3-5子密钥的产生过程
对每个i,,计算,,,其中表示一个或两个位置的左循环移位,当i=时,移一个位置,当i=时,移两个位置。
#include{voidip(intora_bit[],intl[],intr[]);ip置换voidswap(intkey[],intc[],intd[]);种密钥置换选择1voidmove(inta[]);循环左移voidmove1(inta[]);循环左移voidswap1(intk[],intc[],intd[]);种密钥置换2voidyihuo32(intl[],intf[]);feistel异或运算voidyihuo48(inta[],intk[]);voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒voidp_swap(intresult[]);f函数中的置换pvoidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistelvoidip1(intfei_result[64],intip1[64]);ip逆置换charora[8],ora_key[8];intora_bit[64],key[64],k[48];intl[32],r[32],c[28],d[28],fei_result[64],des[8];inti,j,n;intsbox[8][4][16]={1};s盒printf("请输入明文");gets(ora);密码明文for(i=0;i<8;i++)将明文从字母转换成2进制{n=ora[i];for(j=0;j<8;j++){if(n%2==0){ora_bit[i*8+j]=0;}else{ora_bit[i*8+j]=1;}n=n2;}}ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题printf("请输入8位字母种密钥");gets(ora_key);手动输入种密钥for(i=0;i<8;i++)将种密钥从字母转换为2进制{n=ora_key[i];for(j=0;j<8;j++){if(n%2==0){key[i*8+j]=0;}else{key[i*8+j]=1;}n=n2;}}swap(key,c,d);种密钥置换1for(i=0;i<16;i++){if(i==0||i==1||i==8||i==15){move(c);循环左移move(d);循环左移}else{move1(c);move1(d);}swap1(k,c,d);置换2--得到kfeistel(l,r,k,sbox);feistel运算}for(i=0;i<32;i++){fei_result[i]=l[i];fei_result[32+i]=r[i];}汇合feistel输出的l-16和r-16ip1(fei_result,des);进行ip逆置换for(i=0;i<8;i++){printf("%5c",des[i]);}printf("\n");}voidip(intora_bit[],intl[],i
voidip(intora_bit[],intl[],intr[]);ip置换
voidswap(intkey[],intc[],intd[]);种密钥置换选择1
voidmove(inta[]);循环左移
voidmove1(inta[]);循环左移
voidswap1(intk[],intc[],intd[]);种密钥置换2
voidyihuo32(intl[],intf[]);feistel异或运算
voidyihuo48(inta[],intk[]);
voids_box(inta[][6],intsbox[][4][16],intresult[32]);查询s盒
voidp_swap(intresult[]);f函数中的置换p
voidF(intr[],intk[],intresult[],intsbox[][4][16]);feistelF函数
voidfeistel(intl[],intr[],intk[],intsbox[][4][16]);feistel
voidip1(intfei_result[64],intip1[64]);ip逆置换
charora[8],ora_key[8];
intora_bit[64],key[64],k[48];
intl[32],r[32],c[28],d[28],fei_result[64],des[8];
inti,j,n;
intsbox[8][4][16]={1};
s盒
printf("请输入明文");
gets(ora);密码明文
for(i=0;i<8;i++)将明文从字母转换成2进制
n=ora[i];
if(n%2==0)
ora_bit[i*8+j]=0;
ora_bit[i*8+j]=1;
n=n2;
ip(ora_bit,l,r);对转换成2进制的明文进行ip置换------所有返回值无问题
printf("请输入8位字母种密钥");
gets(ora_key);手动输入种密钥
for(i=0;i<8;i++)将种密钥从字母转换为2进制
n=ora_key[i];
key[i*8+j]=0;
key[i*8+j]=1;
swap(key,c,d);种密钥置换1
for(i=0;i<16;i++)
if(i==0||i==1||i==8||i==15)
move(c);循环左移
move(d);循环左移
move1(c);
move1(d);
swap1(k,c,d);置换2--得到k
feistel(l,r,k,sbox);feistel运算
for(i=0;i<32;i++)
fei_result[i]=l[i];
fei_result[32+i]=r[i];
}汇合feistel输出的l-16和r-16
ip1(fei_result,des);进行ip逆置换
printf("%5c",des[i]);
printf("\n");
voidip(intora_bit[],intl[],i
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1