DES加密算法与解密(带流程图)
- 格式:doc
- 大小:255.00 KB
- 文档页数:10
网络与信息安全作业题目:DES加密与解密过程原理解析姓名:学号:班级:日期:2016年3月30日一、DES简介:DES(Data Encryption Standard)是对称加解密算法的一种,由IBM公司W.Tuchman和C.Meyer在上个世纪70年代开发,该算法使用64位密钥(其中包含8位奇偶校验,实际密钥长度为56位)对以64为单位的块数据加密,产生64位密文数据,然后使用相同的密钥进行解密。
密钥只有通信双方知晓,不对第三方公开。
二、DES算法过程:1.DES的加密过程:第一阶段:初始置换IP。
在第一轮迭代之前,需要加密的64位明文首先通过初始置换IP的作用,对输入分组实施置换。
最后,按照置换顺序,DES将64位的置换结果分为左右两部分,第1位到第32位记为L0,第33位到第64位记为R0。
表1:置换IP表上表为置换IP表,将输入64位的第58位换到第一位,第50位换到第二位,依此类推,最后一位是原来的第7位。
L0是输出的前32位,R0是后32位。
比如:置换前的输入值为D1D2D3...D64,则经过初始置换后的结果为:L0=D58D50...D8,R0=D57D49 (7)第二阶段:获取函数f和子密钥。
函数f有两个输入:32位的Ri-1和48位Ki,f函数的处理流程如下图所示。
E变换的算法是从Ri-1的32位中选取某些位,构成48位。
即E 将32比特扩展变换为48位,变换规则根据E位选择表,如表2所示。
表2:E位选择表Ki是由密钥产生的48位比特串,具体的算法下面介绍。
将E的选位结果与Ki作异或操作,得到一个48位输出。
分成8组,每组6位,作为8个S盒的输入。
每个S盒输出4位,共32位(如下图)。
S盒的输出作为P变换的输入,P的功能是对输入进行置换,P换位表如表3所示。
表3:P换位表子密钥Ki:假设密钥为K,长度为64位,但是其中第8、16、24、32、40、48、64用作奇偶校验位,实际上密钥长度为56位。
简述des数据加密算法流程
DES(Data Encryption Standard)是一种对称密钥加密算法,它的加密和解密使用相同的密钥。
DES算法的流程可以分为初始置换、16轮迭代、逆置换三个步骤。
首先是初始置换,将明文按照一定的规则进行置换,得到一个置换后的明文。
这个置换的目的是为了增加加密的难度,使得密文更难被破解。
接下来是16轮迭代,每轮迭代都包括四个步骤:扩展置换、S盒置换、置换、异或。
其中扩展置换将32位的数据扩展为48位,S盒置换将48位数据按照S盒进行置换,置换将置换后的数据进行置换,异或将置换后的数据与密钥进行异或操作。
这16轮迭代的目的是为了增加加密的强度,使得密文更加难以被破解。
最后是逆置换,将16轮迭代后的数据按照一定的规则进行逆置换,得到加密后的密文。
逆置换的目的是为了将加密后的数据还原为原始数据,使得解密操作可以进行。
在DES算法中,密钥长度为64位,但是由于存在奇偶校验位,实际上只有56位是有效的。
因此,DES算法的密钥空间只有2的56次方,这使得DES算法的密钥容易被暴力破解。
为了增加加密的强度,通常会使用3DES算法,即对同一数据进行三次DES加密,使用不同的密钥进行加密,这样可以大大增加加密的强度。
DES算法是一种经典的对称密钥加密算法,它的加密和解密使用相
同的密钥,加密过程包括初始置换、16轮迭代和逆置换三个步骤,其中16轮迭代的目的是为了增加加密的强度,使得密文更加难以被破解。
虽然DES算法的密钥长度较短,但是通过使用3DES算法可以大大增加加密的强度。
实验1-2 对称密码算法DES一.实验原理信息加密根据采用的密钥类型可以划分为对称密码算法和非对称密码算法。
对称密码算法是指加密系统的加密密钥和解密密钥相同,或者虽然不同,但是可以从其中任意一个推导出另一个,更形象的说就是用同一把钥匙开锁和解锁。
在对称密码算法的发展历史中曾出现过多种优秀的算法,包括DES、3DES、AES等。
下面我们以DES算法为例介绍对称密码算法的实现机制。
DES算法是有美国IBM公司在20世纪70年代提出,并被美国政府、美国国家标准局和美国国家标准协会采纳和承认的一种标准加密算法。
它属于分组加密算法,即明文加密和密文解密过程中,信息都是按照固定长度分组后进行处理的。
混淆和扩散是它采用的两个最重要的安全特性,混淆是指通过密码算法使明文和密文以及密钥的关系非常复杂,无法从数学上描述或者统计。
扩散是指明文和密钥中每一位信息的变动,都会影响到密文中许多位信息的变动,从而隐藏统计上的特性,增加密码安全。
DES将明文分成64比特位大小的众多数据块,即分组长度为64位。
同时用56位密钥对64位明文信息加密,最终形成64位的密文。
如果明文长度不足64位,则将其扩展为64位(例如补零等方法)。
具体加密过程首先是将输入的数据进行初始换位(IP),即将明文M 中数据的排列顺序按一定的规则重新排列,生成新的数据序列,以打乱原来的次序。
然后将变换后的数据平分成左右两部分,左边记为L0,右边记为R0,然后对R0施行在子密钥(由加密密钥产生)控制下的变换f,结果记为f(R0 ,K1),再与L0做逐位异或运算,其结果记为R1,R0则作为下一轮的L1。
如此循环16轮,最后得到L16、R16,再对L16、R16施行逆初始置换IP-1,即可得到加密数据。
解密过程与此类似,不同之处仅在于子密钥的使用顺序正好相反。
DES全部16轮的加密过程如图1-1所示。
DES的加密算法包括3个基本函数:1.初始换位(IP)它的作用是把输入的64位数据块的排列顺序打乱,每位数据按照下面换位规则重新组合。
DES加密算法与解密(带流程图)一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_Table置换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};const static char Final_Table[] = { //最终置换40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25};const static char S_Box[8][64] = {//s_box/* S1 */{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},/* S2 */{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10,14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},/* S5 */{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},/* S6 */{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},/* S7 */{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},/* S8 */{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}const static char Rar_Table[] = { //压缩置换14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32};const static char Exp_Table[] = { //扩展置换32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1const static char P_Table[]={ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25};const static char KeyRar_Table[]={57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4};//设置全局变量,16轮密钥bool key[16][48]={{0}};void ByteToBit(bool *Out,char *In,int bits) //字节到位转换函数{int i;for(i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8))&1;}void BitToByte(char *Out,bool *In,int bits)//位到字节转换函数{int i;for(i=0;i<bits/8;i++)Out[i]=0;for(i=0;i<bits;i++)Out[i/8]|=In[i]<<(i%8);}void Xor(bool *InA,const bool *InB,int length) //按位异或for(int i=0;i<length;i++)InA[i]^=InB[i];}void keyfc(char *In) //密钥生成函数{int i,j=0,mov,k,m;bool* key0 = new bool[56];bool* keyin = new bool[64];bool temp;ByteToBit(keyin,In,64); //字节到位的转换for(i=0;i<56;i++) //密钥压缩为56位key0[i]=keyin[KeyRar_Table[i]-1];for(i=0;i<16;i++) //16轮密钥产生{if(i==0||i==1||i==8||i==15)mov=1;elsemov=2;for(k=0;k<mov;k++) //分左右两块循环左移{for(m=0;m<8;m++){temp=key0[m*7];for(j=m*7;j<m*7+7;j++)key0[j]=key0[j+1];key0[m*7+6]=temp;}temp=key0[0];for(m=0;m<27;m++)key0[m]=key0[m+1];key0[27]=temp;temp=key0[28];for(m=28;m<55;m++)key0[m]=key0[m+1];key0[55]=temp;}for(j=0;j<48;j++) //压缩置换并储存key[i][j]=key0[Rar_Table[j]-1];}delete[] key0;delete[] keyin;}void DES(char Out[8],char In[8],bool Type)//加密核心程序,Type=0时加密,反之解密{bool* MW = new bool[64];bool* tmp = new bool[32];bool* PMW = new bool[64];bool* kzmw = new bool[48];bool* keytem = new bool[48];bool* ss = new bool[32];int hang,lie,i;ByteToBit(PMW,In,64);for(int j=0;j<64;j++){MW[j]=PMW[IP_Table[j]-1]; //初始置换}bool *Li=&MW[0],*Ri=&MW[32];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];if(Type==0) //DES加密过程{for(int lun=0;lun<16;lun++){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++)hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}else //DES解密过程{for(int lun=15;lun>=0;lun--){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2; }for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1]; BitToByte(Out,PMW,64); //位到字节的转换}delete[] MW;delete[] tmp;delete[] PMW;delete[] kzmw;delete[] keytem;delete[] ss;}bool RunDes(char *Out, char *In, int datalength, char *Key, bool Type) //加密运行函数,判断输入以及对输入文本8字节分割{if( !( Out && In && Key && (datalength=(datalength+7)&0xfffffff8) ) ) return false;keyfc(Key);for(int i=0,j=datalength%8; i<j; ++i,Out+=8,In+=8)DES(Out, In, Type);return true;}int main(){char* Ki = new char[8];char Enter[]="This is the test of DES!"; char* Print = new char[200];int len = sizeof(Enter);int i_mf;cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Print,Enter,len,Ki,0);//加密cout << "----加密前----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << "\n\n";cout << "----加密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout<<Print[i_mf];cout << "\n\n";//此处进行不同密钥输入测试cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Enter,Print,len,Ki,1);//解密cout << "----解密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << endl;delete[] Ki;delete[] Print;return 0;}二、程序编译、运行结果图:三、程序总体框架图:读取待加密文本输入密钥DES 加密显示加密后文本再次输入密钥DES 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:Enter = 待加密文本分割Enter ,8字节为一段,不足补加,段数为N 初始化:*Print ,i=0,j=0文本第i 段,转为二进制64位初始置换(IP_Table )文本段分为左右两部分左部分(32位)右部分(32)输入8字节密钥转为二进制64位密钥压缩KeyRar_Table (56位)形成16轮密钥合并形成子密钥(48位)S 置换(S_Box )P 置换(P_Table )左右交换,j++最终置换(Final_Table )J<16扩展置换(Exp_Table )i<N异或异或NoYes存入*Print ,i++DES 加密过程结束,输出Print YesNoDES 解密过程为以上逆过程。
数据加密标准DES1977年1月,美国政府将IBM研制的一种乘积密码宣布为国家的数据加密标准。
这个标准的确立刺激了很大一批厂商去实现加密算法的硬件化,以提高处理速度。
这种密码术的核心是乘积变换,在硬件产业中常常简称为DES(Data Encryption Standard)。
这样一来,由于可以得到便宜高速的硬件,所以反过来也鼓励了许多其他用户采纳DES。
1.DES算法描述现在我们来说明DES算法,它的过程如图9-2所示。
对明文按64位分组,每组明文经初始排列(第1步),通过子密钥K1--K16进行16次乘积变换(第2步),再通过最终排列(第3步)得到64位密文。
图9-2 DES算法过程图16次乘积变换的目的是使明文增大其混乱性和扩散性,使得输出不残存统计规律,使破译者不能从反向推算出密钥。
第1步:初始排列(IP)IP(Initial Permutation)取排数据的方法如表9-2所示,其中的数据表示明文的位标(1~64)。
例如,58指该组明文中的第58位,50指该组明文中的第50位,其他类推。
第l步初始排列的目的是将明文的顺序打乱。
表9-2 初始排列法(IP)[例12-1]明文X=0123456789ABCDEF(十六进制形式),写成二进制形式,共64位:X=0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111经过初始排列(IP)后,结果变成:1100 1100 0000 0000 1100 1100 1111 1111 1111 0000 1010 1010 1111 0000 1010 1010即写成十六进制形式是:CC00CCFFFOAAFOAA。
第2步:乘积变换把通过第1步得出的64位一分为二,用L0表示前32位,R0表示后32位,那么在上例中有:L0=CC00CCFF R0=FOAAFOAA其16次乘积变换的过程可以用图9-3表示。
Des加解密算法过程DES加解密算法过程⼊⼝参数有3个:key、data、mode。
key为加密解密使⽤的密钥,data为加密解密的数据,mode为其⼯作模式。
当模式为加密模式时,明⽂按照64位进⾏分组,形成明⽂组,key⽤于数据加密,当模式为解密模式时,key⽤于对数据解密。
实际运⽤中,密钥只⽤到了64位中的56位,这样才具有⾼的安全性。
DES( Data Encryption Standard)算法,于1977年得到美国政府的正式许可,是⼀种⽤56位密钥来加密64位数据的⽅法。
虽然56位密钥的DES算法已经风光不在,⽽且常有⽤Des加密的明⽂被破译的报道,但是了解⼀下昔⽇美国的标准加密算法总是有益的,⽽且⽬前DES算法得到了⼴泛的应⽤,在某些场合,仍然发挥着余热。
DES (Data Encryption Standard),是IBM在上个世纪70年代开发的单密钥对称加解密算法。
该算法⽤⼀个56+8奇偶校验位(第8, 16, 24, 32, 40, 48, 56, 64位)=64位的密钥对以64位为单位的块数据进⾏加解密。
1、⼦密钥的⽣成过程:⽤户输⼊密码时长度不受限制,当⽤户输⼊的密码长度为0时,使⽤缺省64位密码,当输⼊的密码长度⼤于8字节时,前8个字节为有效密码。
我们在加密时设定的密钥先转化成64⽐特的⼆进制,然后再按照密钥置换函数PC-1(8x7)进⾏压缩置换,变成56位,将其置换的输出再分前28位C0和后28位D0两部分。
然后再将此2部分进⾏16轮的循环左移及压缩置换PC-2(8X6),最后⽣成16个48位的字密钥。
1.1 压缩置换到56位假设有密钥K(64位) = 133457799BBCDFF1,即:K(64位) = 00010011 00110100 01010111 0111100110011011 10111100 11011111 11110001其中加粗标注第8位、第16位、第24位、第32位、第40位、第48位、第56位、第64位作为奇偶校验位,不参与计算,即实际密钥为56位。
数据加密标准DES(Data Encryption Standard)算法是由美国IBM公司研制的一种分组密码算法,一种迭代分组密码。
DES是一种使用最为广泛的加密算法,虽然DES出现后又产生了许多常规加密算法,但DES仍是此类算法中最重要的一种。
在正式讨论DES算法之前,为了更好的理解算法的实际工作过程,我们先来看一个简化的DES算法,以此加深对DES算法的理解。
一、简化的DES加密算法简化的DES加密算法是以8bit的明文分组和10bit密钥作为输入,产生8bit 密文分组作为输出。
1、加密流程简化的DES算法基本加密流程如图6.9所示图6.9 简化的DES的加密过程2、加密算法构成:函数、SW置换函简单DES的加密算法包括4个基本函数:初始置换函数IP、fk数、逆置换函数IP-1。
(1)初始置换函数IP初始置换IP是将明文中数据的排列顺序按一定的规则重新排列,而生成新的数据序列的过程。
如图6.10所示:8bit原数据位置 1 2 3 4 5 6 7 8【IP置换】经IP置换后的数据位置 2 6 3 1 4 8 5 7图6.10 简单DES的初始置换例:设8bit数据为11110011 ,则初始置换后的结果为:函数f k函数是多个置换函数和替代函数的组合函数。
f k函数首先将输(2) fk入它的8bit数据进行分组,分成左4位和右4位,然后对右组的4位数据进行E/P扩展置换运算,接着将扩展置换所得的8bit数据与子密钥进行异或运算,再将异或运算所得结果通过S盒输出,再将通过S盒输出的数据进行P4置换,最后将经过P4置换后的数据与输入f函数经分组的左4位数据进行异或运算。
kF(R,SK)函数是f k函数的核心函数,其中SK是子密钥。
F(R,SK)函数的运算方法如下:f k(L,R)=(L⊕F(R,SK),R)L:输入的左边4位分组 R:输入的右边4位分组⊕:逐位异或①扩展/置换是将4bit输入数据经过置换和扩展而产生8bit数据的算法。
实验二DES算法【实验目的】●理解对称加密算法的原理和特点●理解DES算法的加密原理【实验人数】每组2人【系统环境】Windows【网络环境】交换网络结构【实验工具】CIS工具箱。
【实验原理】见《原理篇》实验一|练习二|任务一。
【实验步骤】本练习将主机A和B作为一组,主机C和D作为一组,主机E和F作为一组。
首先使用“快照X”恢复Windows系统环境。
一.DES加密解密(1)本机进入“工具箱”|“加密解密”|“DES加密算法”|“加密/解密”页签,在明文输入区输入明文_computer___________。
(2)在密钥窗口输入8(64位)个字符的密钥k,密钥k=_abcdefg_____.单击“加密”按钮,将密文345F4AEFC63A0E59导出到DES文件夹(D:\Work\Eneryption\DES)中,通告同组主机获取密文,并将密钥k告诉同组主机。
(3)单击“导入”按钮,从同组主机的DES共享文件夹中将密文导入,然后在密钥窗口输入被同组主机通告的密钥k,点击“解密”按钮进行DES解密。
(4)将破解后的明文与同组主机记录的明文比较。
二.DES算法进入“工具箱”|“加密解密”|“DES加密算法”|“演示”页签。
输入64位明文与密钥,执行加密操作,查看各演示模块。
在DES加密算法中,S-代替是最重要的部分,与其它代替比较起来,它提供了更好的安全性。
因此,掌握S-盒代替是掌握DES算法的关键。
由于加密软件与加密硬件本身的特点有很在的差异,所以在实现DES加密算法时,加密软件与加密硬件采用的不同的策略。
加密硬件一般采取标准折DES加密算法实现,高加密率是加密硬件的主要特点。
加密软件为了提高加密的效率,要遵守以下原则:●展开加密循环与函数;●避免内部循环中使用条件转移指令;●变量长度与CPU内部寄存器长度相同;限制变量数量;●避免使用耗时的指令。
所以,加密软件在实现DES算法时,一般都对算法加以修改,以提高加密效率。
DES的加密与解密算法(Python实现)DES的加密与解密算法(Python实现)密码学实验:实现了DES的简单的加密和解密算法,DES算法的相关资料⽹上很多,这⾥不再赘述,仅仅贴出源代码给⼤家分享,源码中包含很多汉字注释,相信⼤家都是可以读懂的。
为了⽅便阅读和理解DES算法的原理,这⾥我将代码进⾏了模块化,分为了四个模块:密钥⽣成模块、F函数模块、DES 加密模块、DES解密模块。
注:DES的加密算法和解密算法⼏乎是⼀模⼀样的,仅仅是密钥的使⽤顺序不同,所以模块的代码也⼏乎没有什么区别。
输⼊输出要求是16个⼗六进制的字符,刚好是64bit!转载请注明出处:密钥⽣成模块:1 MaxTime = 162#⽣成⼦密钥的置换表1,将64位的密钥转换为56位3 key_table1=[ 57, 49, 41, 33, 25, 17, 9,4 1, 58, 50, 42, 34, 26, 18,5 10, 2, 59, 51, 43, 35, 27,6 19, 11, 3, 60, 52, 44, 36,7 63, 55, 47, 39, 31, 23, 15,8 7, 62, 54, 46, 38, 30, 22,9 14, 6, 61, 53, 45, 37, 29,10 21, 13, 5, 28, 20, 12, 4 ]11#⽣成⼦密钥的置换表2,将56位的密钥转换为48位12 key_table2=[ 14, 17, 11, 24, 1, 5,13 3, 28, 15, 6, 21, 10,14 23, 19, 12, 4, 26, 8,15 16, 7, 27, 20, 13, 2,16 41, 52, 31, 37, 47, 55,17 30, 40, 51, 45, 33, 48,18 44, 49, 39, 56, 34, 53,19 46, 42, 50, 36, 29, 32 ]2021def Listmove(l, step): #将列表中的元素循环左移22return l[step:] + l[:step]2324def Subkey(key): #⽣成⼦密钥25 keyresult = []26 key0 = [0 for i in range(56)]2728for i in range(len(key_table1)):29 key0[i] = key[key_table1[i]-1]3031#⽣成16个密钥32for i in range(MaxTime):33 key1 = [0 for i in range(48)]34#确定每次左移的步数35if (i == 0 or i == 1 or i == 8 or i == 15):36 step = 137else:38 step = 239#分成两组40 tmp1 = key0[0:28]41 tmp2 = key0[28:56]42#循环左移43 tmp1 = Listmove(tmp1, step)44 tmp2 = Listmove(tmp2, step)45#左右连接46 key0 = tmp1 + tmp247#置换选择48for i in range(len(key_table2)):49 key1[i] = key0[key_table2[i]-1]50#⽣成密钥51 keyresult.append(key1)52#返回的是⼀个集合包含了每次的密钥53return keyresultF函数模块:1 MaxTime = 162#IP置换表3 IP_table=[58, 50, 42, 34, 26, 18, 10, 2,4 60, 52, 44, 36, 28, 20, 12, 4,5 62, 54, 46, 38, 30, 22, 14, 6,6 64, 56, 48, 40, 32, 24, 16, 8,7 57, 49, 41, 33, 25, 17, 9, 1,8 59, 51, 43, 35, 27, 19, 11, 3,9 61, 53, 45, 37, 29, 21, 13, 5,10 63, 55, 47, 39, 31, 23, 15, 7 ]11#逆IP置换表12 Inv_IP_table=[40, 8, 48, 16, 56, 24, 64, 32,13 39, 7, 47, 15, 55, 23, 63, 31,14 38, 6, 46, 14, 54, 22, 62, 30,15 37, 5, 45, 13, 53, 21, 61, 29,16 36, 4, 44, 12, 52, 20, 60, 28,17 35, 3, 43, 11, 51, 19, 59, 27,18 34, 2, 42, 10, 50, 18, 58, 26,19 33, 1, 41, 9, 49, 17, 57, 25 ]20#S盒中的S1盒21 S1=[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,22 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,23 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,24 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 ] 25#S盒中的S2盒26 S2=[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,27 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,28 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,29 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 ] 30#S盒中的S3盒31 S3=[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,32 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,33 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,34 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 ] 35#S盒中的S4盒36 S4=[ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,37 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,38 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,39 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 ] 40#S盒中的S5盒41 S5=[ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,42 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,43 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,44 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 ] 45#S盒中的S6盒46 S6=[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,47 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,48 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,49 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 ] 50#S盒中的S7盒51 S7=[ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,52 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,53 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,54 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12] 55#S盒中的S8盒56 S8=[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,57 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,58 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,59 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ] 60# S盒61 S=[S1,S2,S3,S4,S5,S6,S7,S8]62#⽤于对数据进⾏扩展置换,将32bit数据扩展为48bit63 extend_table=[32, 1, 2, 3, 4, 5,64 4, 5, 6, 7, 8, 9,65 8, 9, 10, 11, 12, 13,66 12, 13, 14, 15, 16, 17,67 16, 17, 18, 19, 20, 21,68 20, 21, 22, 23, 24, 25,69 24, 25, 26, 27, 28, 29,70 28, 29, 30, 31, 32, 1 ]71#P盒72 P_table=[ 16, 7, 20, 21, 29, 12, 28, 17,73 1, 15, 23, 26, 5, 18, 31, 10,74 2, 8, 24, 14, 32, 27, 3, 9,75 19, 13, 30, 6, 22, 11, 4, 25 ]7677def int2bit(n):#0~15整数转⽐特78 a=[]79for i in range(0,4):80 a.insert(0,str(n%2))81 n=int(n/2)82return a8384#IP置换部分,op为0表⽰正置换,op为1表⽰逆置换85def IP(text, op):86 tmp = [0 for i in range(64)]87if op == 0:88for i in range(64):89 tmp[i] = text[IP_table[i]-1]90return tmp91if op == 1:92for i in range(64):93 tmp[i] = text[Inv_IP_table[i]-1]94return tmp95#进⾏扩展,将32位扩展为48位96def Extend(text):97 extend = [0 for i in range(48)]98for i in range(48):99 extend[i] = text[extend_table[i] - 1]100return extend101102#S盒变换部分103def S_replace(text):104 Sresult = [0 for k in range(32)]105for k in range(8):106 row = 2*int(text[k*6]) + int(text[k*6+5])107 column = 8*int(text[k*6+1]) + 4*int(text[k*6+2]) + 2*int(text[k*6+3]) + int(text[k*6+4]) 108 tmp = S[k][row*16+column]109110for i in range(4):111 Sresult[4*k + i] = int2bit(tmp)[i]112return Sresult113#P置换部分114def P_replace(text):115 Presult = [0 for i in range(32)]116for i in range(32):117 Presult[i] = text[P_table[i]-1]118return Presult119#异或运算120def Xor(bit1, bit2):121 Xorresult = [0 for i in range(len(bit1))]122for i in range(len(bit1)):123 Xorresult[i] = str(int(bit1[i]) ^ int(bit2[i]))124return XorresultDES加密模块:1import CreateSubkey as cs2import F_function as f3#⼗六进制转⼆进制⽐特串4def Hex2bin(text):5 result = []6for i in range(len(text)):7 result.extend(f.int2bit(int(text[i],16)))8return result9#⼆进制⽐特串转⼗六进制10def bin2Hex(text):11 result = []12 q = len(text)//413for i in range(q):14 dec = int(text[4*i])*8 + int(text[4*i+1])*4 + int(text[4*i+2])*2 + int(text[4*i+3])*115 x = hex(dec)[2:].upper()16 result.extend(x)17 rs = ''.join(result)18return rs19#按照DES算法的流程图进⾏运算20def Encryption(text, key):21 keylist = cs.Subkey(keybit)22 text1 = f.IP(text, 0) #IP置换23 L = [text1[i] for i in range(32)]24 R = [text1[i] for i in range(32,64)]25for i in range(16):26 tmp = R27 tmp = f.Extend(tmp)28 tmp = f.Xor(tmp, keylist[i])29 tmp = f.S_replace(tmp)30 tmp = f.P_replace(tmp)31 tmp = f.Xor(tmp, L)32 L = R33 R = tmp34 L,R = R,L35 ctext = L36 ctext.extend(R)37 ctext = f.IP(ctext, 1)38return bin2Hex(ctext)3940if__name__ == '__main__':41 plaintext = input('请输⼊⽤⼗六进制表⽰的明⽂:')42 key = input('请输⼊⽤⼗六进制表⽰的密钥:')43 ptext = Hex2bin(plaintext)44 keybit = Hex2bin(key)45print('输出的密⽂为:' + Encryption(ptext, keybit))DES解密模块:1import CreateSubkey as cs2import F_function as f3#⼗六进制转⼆进制⽐特串4def Hex2bin(text):5 result = []6for i in range(len(text)):7 result.extend(f.int2bit(int(text[i],16)))8return result9#⼆进制⽐特串转⼗六进制10def bin2Hex(text):11 result = []12 q = len(text)//413for i in range(q):14 dec = int(text[4*i])*8 + int(text[4*i+1])*4 + int(text[4*i+2])*2 + int(text[4*i+3])*115 x = hex(dec)[2:].upper()16 result.extend(x)17 rs = ''.join(result)18return rs1920def Encryption(text, key):21 keylist = cs.Subkey(keybit)22 text1 = f.IP(text, 0) #IP置换23 L = [text1[i] for i in range(32)]24 R = [text1[i] for i in range(32,64)]25for i in range(16):26 tmp = R27 tmp = f.Extend(tmp)28 tmp = f.Xor(tmp, keylist[15-i])29 tmp = f.S_replace(tmp)30 tmp = f.P_replace(tmp)31 tmp = f.Xor(tmp, L)32 L = R33 R = tmp34 L,R = R,L35 ctext = L36 ctext.extend(R)37 ctext = f.IP(ctext, 1)38return bin2Hex(ctext)3940if__name__ == '__main__':41 plaintext = input('请输⼊⽤⼗六进制表⽰的密⽂:')42 key = input('请输⼊⽤⼗六进制表⽰的密钥:')43 ptext = Hex2bin(plaintext)44 keybit = Hex2bin(key)45print('输出的明⽂为:' + Encryption(ptext, keybit))。
DES算法详解 本⽂主要介绍了DES算法的步骤,包括IP置换、密钥置换、E扩展置换、S盒代替、P盒置换和末置换。
1.DES算法简介 DES算法为密码体制中的对称密码体制,⼜被称为美国数据加密标准。
DES是⼀个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密⽤的是同⼀个算法。
密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1),分组后的明⽂组和56位的密钥按位替代或交换的⽅法形成密⽂组。
DES算法的主要流程如下图所⽰,本⽂按照流程依次介绍每个模块。
2.IP置换 IP置换⽬的是将输⼊的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位。
置换规则如下表所⽰:58504234261810260524436282012462544638302214664564840322416857494133251791595143352719113615345372921135635547393123157 表中的数字代表新数据中此位置的数据在原数据中的位置,即原数据块的第58位放到新数据的第1位,第50位放到第2位,……依此类推,第7位放到第64位。
置换后的数据分为L0和R0两部分,L0为新数据的左32位,R0为新数据的右32位。
要注意⼀点,位数是从左边开始数的,即最0x0000 0080 0000 0002最左边的位为1,最右边的位为64。
3.密钥置换 不考虑每个字节的第8位,DES的密钥由64位减⾄56位,每个字节的第8位作为奇偶校验位。
产⽣的56位密钥由下表⽣成(注意表中没有8,16,24,32,40,48,56和64这8位):57494133251791585042342618102595143352719113605244366355473931231576254463830221466153453729211352820124 在DES的每⼀轮中,从56位密钥产⽣出不同的48位⼦密钥,确定这些⼦密钥的⽅式如下: 1).将56位的密钥分成两部分,每部分28位。
实验一的报告DES简介英文Data Encryption Standard1977年美国国家标准局公布了IBM公司研制的一种数据加密算法:数据加密标准。
原定服役十年,由于在这期间,该加密标准没有受到真正的威胁,20多年来一直活跃在国际保密通信的舞台上。
近些年,随着计算机技术的提高,已经有了现实的威胁。
512位的密钥已经能被破解,但是要花很多的时间,计算量非常大,1024位长度密钥至今没能被破解。
DES作为一种高速对称加密算法,仍然具有重要意义,特别是DES(密钥系统)和公钥系统结合组成混合密码系统。
使DES和公钥系统(如RSA)能够各自扬长避短,提高了加密系统的安全和效率。
DES的加密解密的通用流程图对于DES,其实就是一种分组密码的一种,即对称密钥加密算法(收发双方使用相同密钥的密码),相信经过学习已经有了初步了解。
那么可以通过其加密与解密的通用流程来进一步巩固所学知识。
如图1图1 对称密钥加密算法流程图想要深一步学习DES,就要学会其算法结构。
如图2图2 DES 算法结构图公开密钥算法收发双方使用不同密钥的密码,就叫非对称密码,下面从其加密解密的通用流程图作一个简单介绍。
如图3图3公开密钥算法通用流程图公开密钥有两个重要特点:仅根据密码算法和加密密钥来确定解密密钥在计算上不可行,两个密钥中的任何一个都可用来加密,另一个用来解密。
公开密钥的加密解密过程如下:明文 密文1、网路中的每个端系统都产生一对用于将接收到的报文进行加密和解密的密钥。
2、每个系统都把公钥公布,私钥就自己保管。
3、如果甲想给乙发送一个报文,甲就用乙的公开密钥来加密报文。
4、乙收到报文就用自己的私钥解密。
对称密钥与公开密钥的区别与联系必须保密,公钥可以公开,关于管理和发布对称加密比较复杂。
对称密钥算法具有加密处理简单,加解密速度快,密钥较短,发展历史悠久等特点,非对称密钥算法具有加解密速度慢的特点,密钥尺寸大,发展历史较短等特点。
信息编码技术实验报告四题目:DES数据加密院系:计算机科学与工程学院班级:姓名:学号:【实验目的】1. 理解对称加密算法的原理和特点。
2. 理解DES算法的加密原理。
【实验条件】仪器设备:PC机,应用软件:Matlab。
【实验内容】DES算法的加密流程图:DES算法的参数:密钥长度56比特,输入明文64比特,输出密文64比特。
根据DES算法的介绍,自己创建明文信息,并选择一个密钥,编写DES密码算法的实现程序,实现加密和解密操作。
【程序代码】% Full D.E.S.clear allclc%Mensaje:M = hex2bin('0123456789ABCDEF');Llaves = GenKeys(hex2bin('133457799BBCDFF1'));L0R0 = IP(M);L = ''; R = '';L = cat(1, L, L0R0(1:32));R = cat(1, R, L0R0(33:64));fprintf('-------------------------------------------------\n');for i=2:1:17Ex = E(R(i-1,:));Kn = Llaves(i-1,:);Xrs= xorS(Ex, Kn);BCajas = SBoxes(Xrs);Fn = F(R(i-1,:),i-1,Llaves);Rn = xorS(L(i-1,:),Fn);fprintf('E(R%i) : ',i-2); disp(Ex);fprintf('K%i : ',i-1); disp(Kn);fprintf('E(R%i)+K%i: ',i-2,i-1); disp(Xrs);fprintf('S-Boxes : '); disp(BCajas);fprintf('f(R%i,K%i): ',i-2,i-1); disp(Fn);fprintf('L%i=R%i : ',i-1,i-2); disp(Rn);L = cat(1, L, R(i-1,:));R = cat(1, R, Rn);fprintf('-------------------------------------------------\n'); endCipher = iIP(cat(2,R(size(R,1),:),L(size(L,1),:)));LetraBin = ''; TextoCifHex = '';for i=1:4:size(Cipher,2)LetraBin = Cipher(i:i+3);TextoCifHex = cat(2, TextoCifHex, dec2hex(bin2dec(LetraBin))) ;endfprintf('\n Texto Cifrado en Hexadecimal: %s \n', TextoCifHex);【实验结果】E(R0) : 011110100001010101010101011110100001010101010101K1 : 000110110000001011101111111111000111000001110010E(R0)+K1: 011000010001011110111010100001100110010100100111S-Boxes : 01011100100000101011010110010111f(R0,K1): 00100011010010101010100110111011L1=R0 : 11101111010010100110010101000100-------------------------------------------------E(R1) : 011101011110101001010100001100001010101000001001 K2 : 011110011010111011011001110110111100100111100101 E(R1)+K2: 000011000100010010001101111010110110001111101100 S-Boxes : 11111000110100000011101010101110f(R1,K2): 00111100101010111000011110100011L2=R1 : 11001100000000010111011100001001-------------------------------------------------E(R2) : 111001011000000000000010101110101110100001010011 K3 : 010101011111110010001010010000101100111110011001 E(R2)+K3: 101100000111110010001000111110000010011111001010 S-Boxes : 00100111000100001110000101101111f(R2,K3): 01001101000101100110111010110000L3=R2 : 10100010010111000000101111110100-------------------------------------------------E(R3) : 010100000100001011111000000001010111111110101001 K4 : 011100101010110111010110110110110011010100011101 E(R3)+K4: 001000101110111100101110110111100100101010110100 S-Boxes : 00100001111011011001111100111010f(R3,K4): 10111011001000110111011101001100L4=R3 : 01110111001000100000000001000101-------------------------------------------------E(R4) : 101110101110100100000100000000000000001000001010 K5 : 011111001110110000000111111010110101001110101000 E(R4)+K5: 110001100000010100000011111010110101000110100010 S-Boxes : 01010000110010000011000111101011f(R4,K5): 00101000000100111010110111000011L5=R4 : 10001010010011111010011000110111-------------------------------------------------E(R5) : 110001010100001001011111110100001100000110101111 K6 : 011000111010010100111110010100000111101100101111 E(R5)+K6: 101001101110011101100001100000001011101010000000 S-Boxes : 01000001111100110100110000111101f(R5,K6): 10011110010001011100110100101100L6=R5 : 11101001011001111100110101101001-------------------------------------------------E(R6) : 111101010010101100001111111001011010101101010011 K7 : 111011001000010010110111111101100001100010111100 E(R6)+K7: 000110011010111110111000000100111011001111101111 S-Boxes : 00010000011101010100000010101101f(R6,K7): 10001100000001010001110000100111L7=R6 : 00000110010010101011101000010000-------------------------------------------------E(R7) : 000000001100001001010101010111110100000010100000 K8 : 111101111000101000111010110000010011101111111011 E(R7)+K8: 111101110100100001101111100111100111101101011011S-Boxes : 01101100000110000111110010101110f(R7,K8): 00111100000011101000011011111001L8=R7 : 11010101011010010100101110010000-------------------------------------------------E(R8) : 011010101010101101010010101001010111110010100001 K9 : 111000001101101111101011111011011110011110000001 E(R8)+K9: 100010100111000010111001010010001001101100100000S-Boxes : 00010001000011000101011101110111f(R8,K9): 00100010001101100111110001101010L9=R8 : 00100100011111001100011001111010-------------------------------------------------E(R9) : 000100001000001111111001011000001100001111110100 K10 : 101100011111001101000111101110100100011001001111 E(R9)+K10: 101000010111000010111110110110101000010110111011 S-Boxes : 11011010000001000101001001110101f(R9,K10): 01100010101111001001110000100010L10=R9 : 10110111110101011101011110110010-------------------------------------------------E(R10) : 010110101111111010101011111010101111110110100101 K11 : 001000010101111111010011110111101101001110000110 E(R10)+K11: 011110111010000101111000001101000010111000100011 S-Boxes : 01110011000001011101000100000001f(R10,K11): 11100001000001001111101000000010L11=R10 : 11000101011110000011110001111000-------------------------------------------------E(R11) : 011000001010101111110000000111111000001111110001 K12 : 011101010111000111110101100101000110011111101001 E(R11)+K12: 000101011101101000000101100010111110010000011000 S-Boxes : 01111011100010110010011000110101f(R11,K12): 11000010011010001100111111101010L12=R11 : 01110101101111010001100001011000-------------------------------------------------E(R12) : 001110101011110111111010100011110000001011110000 K13 : 100101111100010111010001111110101011101001000001 E(R12)+K13: 101011010111100000101011011101011011100010110001 S-Boxes : 10011010110100011000101101001111f(R12,K13): 11011101101110110010100100100010L13=R12 : 00011000110000110001010101011010-------------------------------------------------E(R13) : 000011110001011000000110100010101010101011110100K14 : 010111110100001110110111111100101110011100111010E(R13)+K14: 010100000101010110110001011110000100110111001110S-Boxes : 01100100011110011001101011110001f(R13,K14): 10110111001100011000111001010101L14=R13 : 11000010100011001001011000001101-------------------------------------------------E(R14) : 111000000101010001011001010010101100000001011011K15 : 101111111001000110001101001111010011111100001010E(R14)+K15: 010111111100010111010100011101111111111101010001S-Boxes : 10110010111010001000110100111100f(R14,K15): 01011011100000010010011101101110L15=R14 : 01000011010000100011001000110100-------------------------------------------------E(R15) : 001000000110101000000100000110100100000110101000K16 : 110010110011110110001011000011100001011111110101E(R15)+K16: 111010110101011110001111000101000101011001011101S-Boxes : 10100111100000110010010000101001f(R15,K16): 11001000110000000100111110011000L16=R15 : 00001010010011001101100110010101-------------------------------------------------Texto Cifrado en Hexadecimal: 85E813540F0AB405【思考题】1.DES从加密原理上归为哪一类(私钥体制或公钥体制)。
计算机⽹络安全——对称加密算法DES(⼀)⼀、对称加密算法概念我们通过计算机⽹络传输数据时,如果⽆法防⽌他⼈窃听,可以利⽤密码学技术将发送的数据变换成对任何不知道如何做逆变换的⼈都不可理解的形式,从⽽保证了数据的机密性。
这种变换被称为加密( encryption),被加密的数据被称为密⽂( ciphertext),⽽加密前的数据被称为明⽂( plaintext)。
接收⽅必须能通过某种逆变换将密⽂重新变换回原来的明⽂,该逆变换被称为解密(decryption)。
加密和解密过程可以以⼀个密钥( key)为参数,并且加密和解密过程可以公开,⽽只有密钥需要保密。
即只有知道密钥的⼈才能解密密⽂,⽽任何⼈,即使知道加密或解密算法也⽆法解密密⽂。
加密密钥和解密密钥可以相同,也可以不同,取决于采⽤的是对称密钥密码体制还是公开密钥密码体制。
所谓对称密钥密码体制是⼀种加密密钥与解密密钥相同的密码体制。
在这种加密系统中,两个参与者共享同⼀个秘密密钥,如果⽤⼀个特定的密钥加密⼀条消息,也必须要使⽤相同的密钥来解密该消息。
该系统⼜称为对称密钥系统。
数据加密标准( Data Encryption Standard, DES)是对称密钥密码的典型代表,由IBM公司研制,于1977年被美国定为联邦信息标准。
其加密解密基本流程如下图:⼆、.NET 使⽤ DES 加密DES使⽤的密钥为64 位(实际密钥长度为56 位,有8位⽤于奇偶校验)。
密码的字节长度不能低于64位(8个字节),下⾯是实现代码:1 using System;2 using System.IO;3 using System.Linq;4 using System.Security.Cryptography;5 using System.Text;67 namespace encryption.des8 {9 /// <summary>10 /// DES 加密与解密11 /// DES加密:https:///question/3676782912 /// 加密基本知识:https:///des.html13 /// </summary>14 public class DesAlgorithm15 {16 public Encoding Encoding { get; set; }17 public PaddingMode Padding { get; set; }18 public CipherMode Mode { get; set; }19 public string PassWord { get; private set; }20 private DESCryptoServiceProvider _des;2122 #region .ctor2324 public DesAlgorithm()25 {26 _des = new DESCryptoServiceProvider();27 PassWord = Convert.ToBase64String(_des.Key);28 Encoding = Encoding.UTF8;29 Padding = PaddingMode.PKCS7;30 Mode = CipherMode.CBC;31 }32 #endregion333435 /// <summary>36 /// 通过字符串⽣成新的密钥37 /// </summary>38 /// <param name="password">密码</param>39 /// <returns></returns>40 public DESCryptoServiceProvider CreateNewkey(string password)41 {42 try43 {44 byte[] buffer = Encoding.GetBytes(password).Skip(0).Take(8).ToArray();45 _des = new DESCryptoServiceProvider()46 {47 Key = buffer,48 IV=buffer,49 };50 PassWord = password;51 return _des;52 }53 catch (Exception e)54 {55 Console.WriteLine($"Wrong Length:{e.Message},{e.InnerException}");56 return null;57 }58 }5960 /// <summary>61 /// DES加密62 /// </summary>63 /// <param name="pToEncrypt">需要加密的字符串<see cref="string"/></param>64 /// <returns></returns>65 public string Encrypt(string pToEncrypt)66 {67 byte[] inputByteArray = Encoding.GetBytes(pToEncrypt);68 return Convert.ToBase64String(this.Encrypt(inputByteArray));69 }7071 /// <summary>72 /// DES加密73 /// </summary>74 /// <param name="pToEncrypt">待加密的byte数组<see cref="byte"/></param>75 /// <returns></returns>76 public byte[] Encrypt(byte[] pToEncrypt)77 {78 byte[] base64 = null;79 using (var ms = new MemoryStream())80 {81 using (var cs = new CryptoStream(ms, _des.CreateEncryptor(), CryptoStreamMode.Write))82 {83 cs.Write(pToEncrypt, 0, pToEncrypt.Length);84 cs.FlushFinalBlock();85 }86 base64 = ms.ToArray();87 }88 return base64;89 }9091 /// <summary>92 /// DES解密93 /// </summary>94 /// <param name="pToDecrypt">需要解密的字符串</param>95 /// <returns></returns>96 public string Decrypt(string pToDecrypt)97 {98 byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);99 return Encoding.GetString(this.Decrypt(inputByteArray));100 }101102 /// <summary>103 /// DES解密104 /// </summary>105 /// <param name="pToDecrypt">待解密的byte数组<see cref="byte"/></param>106 /// <returns></returns>107 public byte[] Decrypt(byte[] pToDecrypt)108 {109 byte[] data = null;110 using (var ms = new MemoryStream())111 {112 using (CryptoStream cs = new CryptoStream(ms, _des.CreateDecryptor(), CryptoStreamMode.Write))113 {114 cs.Write(pToDecrypt, 0, pToDecrypt.Length);115 cs.FlushFinalBlock();116 }117 data = ms.ToArray();118 }119 return data;120 }121 }122 }三、.NET 使⽤ 3DES 加密DES使⽤的密钥为64 位,它是⼀个优秀的密码算法,⽬前还没有发现⽐蛮⼒攻击更好的破解⽅法。
课程名称现代密码学实验实验项目名称 DES算法【实验目的】1.理解对称加密算法的原理和特点。
2.理解DES算法的加密原理。
【实验环境】1.实验人数:每组2人2.系统环境:Windows3.网络环境:交换网络结构4.实验工具:VC++6.0、密码工具【实验原理】一.对称密钥加密机制对称密钥加密机制即对称密码体系,也称为单钥密码体系和传统密码体系。
对称密码体系通常分为两大类,一类是分组密码(如DES、AES算法),另一类是序列密码(如RC4算法)。
对称密码体系加密和解密时所用的密钥是相同的或者是类似的,即由加密密钥可以很容易地推导出解密密钥,反之亦然。
同时在一个密码系统中,我们不能假定加密算法和解密算法是保密的,因此密钥必须保密。
发送信息的通道往往是不可靠的或者不安全的,所以在对称密码系统中,必须用不同于发送信息的另外一个安全信道来发送密钥。
图1描述了对称密码(传统密码)系统原理框架,其中M表示明文;C表示密文;E表示加密算法;D表示解密算法;K表示密钥;I表示密码分析员进行密码分析时掌握的相关信息;B表示密码分析员对明文M的分析和猜测。
图1 传统密码系统原理框架图对称密码体系的优点:●加密效率高,硬件实现可达每秒数百兆字节(软件实现略慢一些)。
●密钥相对比较短。
●可以用来构造各种密码机制。
●可以用来建造安全性更强的密码。
对称密码体系的缺点:●通信双方都要保持密钥的秘密性。
●在大型网络中,每个人需持有许多密钥。
●为了安全,需要经常更换密钥。
二.DES加密算法简介1973年5月15日,美国国家标准局在联邦注册报上发表一则启事,公开征集用来保护传输和静止存储的计算机数据的密码算法,这一举措最终导致了数据加密标准DES的出现。
DES采用分组乘积密码体制,它是由IBM开发的,是对早期Lucifer密码体制的改进。
DES 在1975年3月17日首次在联邦记录中公布,而且声明对此算法征求意见。
到1977年2月15日拟议中的DES被采纳为“非密级”应用的一个联邦标准。
DES加密算法与解密(带流程图)一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_Table置换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};const static char Final_Table[] = { //最终置换40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25};const static char S_Box[8][64] = {//s_box/* S1 */{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},/* S2 */{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10,6, 9, 11, 5,0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},/* S3 */{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},/* S4 */{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3,14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},/* S5 */{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},/* S6 */{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7,6, 0, 8, 13},/* S7 */{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},/* S8 */{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};const static char Rar_Table[] = { //压缩置换14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32};const static char Exp_Table[] = { //扩展置换32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1};const static char P_Table[]={ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25};const static char KeyRar_Table[]={57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4};//设置全局变量,16轮密钥bool key[16][48]={{0}};void ByteToBit(bool *Out,char *In,int bits) //字节到位转换函数{int i;for(i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8))&1;}void BitToByte(char *Out,bool *In,int bits)//位到字节转换函数{int i;for(i=0;i<bits/8;i++)Out[i]=0;for(i=0;i<bits;i++)Out[i/8]|=In[i]<<(i%8);}void Xor(bool *InA,const bool *InB,int length) //按位异或{for(int i=0;i<length;i++)InA[i]^=InB[i];}void keyfc(char *In) //密钥生成函数{int i,j=0,mov,k,m;bool* key0 = new bool[56];bool* keyin = new bool[64];bool temp;ByteToBit(keyin,In,64); //字节到位的转换for(i=0;i<56;i++) //密钥压缩为56位key0[i]=keyin[KeyRar_Table[i]-1];for(i=0;i<16;i++) //16轮密钥产生{if(i==0||i==1||i==8||i==15)mov=1;elsemov=2;for(k=0;k<mov;k++) //分左右两块循环左移{for(m=0;m<8;m++){temp=key0[m*7];for(j=m*7;j<m*7+7;j++)key0[j]=key0[j+1];key0[m*7+6]=temp;}temp=key0[0];for(m=0;m<27;m++)key0[m]=key0[m+1];key0[27]=temp;temp=key0[28];for(m=28;m<55;m++)key0[m]=key0[m+1];key0[55]=temp;}for(j=0;j<48;j++) //压缩置换并储存key[i][j]=key0[Rar_Table[j]-1];}delete[] key0;delete[] keyin;}void DES(char Out[8],char In[8],bool Type)//加密核心程序,Type=0时加密,反之解密{bool* MW = new bool[64];bool* tmp = new bool[32];bool* PMW = new bool[64];bool* kzmw = new bool[48];bool* keytem = new bool[48];bool* ss = new bool[32];int hang,lie,i;ByteToBit(PMW,In,64);for(int j=0;j<64;j++){MW[j]=PMW[IP_Table[j]-1]; //初始置换}bool *Li=&MW[0],*Ri=&MW[32];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];if(Type==0) //DES加密过程{for(int lun=0;lun<16;lun++){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}else //DES解密过程{for(int lun=15;lun>=0;lun--){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}delete[] MW;delete[] tmp;delete[] PMW;delete[] kzmw;delete[] keytem;delete[] ss;}bool RunDes(char *Out, char *In, int datalength, char *Key, bool Type) //加密运行函数,判断输入以及对输入文本8字节分割{if( !( Out && In && Key && (datalength=(datalength+7)&0xfffffff8) ) ) return false;keyfc(Key);for(int i=0,j=datalength%8; i<j; ++i,Out+=8,In+=8)DES(Out, In, Type);return true;}int main(){char* Ki = new char[8];char Enter[]="This is the test of DES!"; char* Print = new char[200];int len = sizeof(Enter);int i_mf;cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Print,Enter,len,Ki,0);//加密cout << "----加密前----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << "\n\n";cout << "----加密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout<<Print[i_mf];cout << "\n\n";//此处进行不同密钥输入测试cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Enter,Print,len,Ki,1);//解密cout << "----解密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << endl;delete[] Ki;delete[] Print;return 0;}二、程序编译、运行结果图:三、程序总体框架图:读取待加密文本输入密钥DES 加密显示加密后文本再次输入密钥DES 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:Enter = 待加密文本分割Enter ,8字节为一段,不足补加,段数为N 初始化:*Print ,i=0,j=0文本第i 段,转为二进制64位初始置换(IP_Table )文本段分为左右两部分左部分(32位)右部分(32)输入8字节密钥转为二进制64位密钥压缩KeyRar_Table (56位)形成16轮密钥合并形成子密钥(48位)S 置换(S_Box )P 置换(P_Table )左右交换,j++最终置换(Final_Table )J<16扩展置换(Exp_Table )i<N异或异或NoYes存入*Print ,i++DES 加密过程结束,输出Print YesNoDES 解密过程为以上逆过程。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,首先,DES把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,并进行前后置换(输入的第58位换到第一位,第50位换到第2位,依此类推,最后一位是原来的第7位),最终由L0输出左32位,R0输出右32位,根据这个法则经过16次迭代运算后,得到L16、R16,将此作为输入,进行与初始置换相反的逆置换,即得到密文输出。
DES算法的入口参数有三个:Key、Data、Mode。
其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密,如果Mode为加密,则用Key去把数据Data进行加密,生成Data的密码形式作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式作为DES的输出结果。
在使用DES时,双方预先约定使用的”密码”即Key,然后用Key去加密数据;接收方得到密文后使用同样的Key解密得到原数据,这样便实现了安全性较高的数据传输。
DES加密算法的过程:1. 对输入的密钥进行变换。
用户的64bit密钥,其中第8,16,24,32,40,48,56,64位是校验位,使得每个密钥都有奇数个1。
所以密钥事实上是56位。
对这56位密钥进行如下表的换位。
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4,表的意思是第57位移到第1位,第49位移到第2位,...... 以此类推。
********************本科生作业********************兰州理工大学计算机与通信学院2017年春季学期信息安全课程专业:物联网工程姓名:学号:授课教师:**成绩:DES加解密过程及其实现1 DES加解密原理DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。
明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
其入口参数有三个:key、data、mode。
key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。
当模式为加密模式时,明文按照64位进行分组,形成明文组,key 用于对数据加密,当模式为解密模式时,key用于对数据解密。
实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。
1.1 DES算法总体描述及流程图DES是一个分组加密算法,它以64位为分组对数据加密。
64位一组的明文从算法的一端输入,64位的密文从另一段输出。
它是一个对称算法:加密和解密用的是同一个算法。
密钥通常表示为64位的数,但每个第8位都用作奇偶校验,可以忽略,所以密钥长度为56位。
密钥可以是任意的56位的数,且可在任意的时候改变。
对于任意的加密方案,总有两个输入:明文和密钥。
DES的明文长为64位,密钥长为56位。
明文的处理一般经过三个阶段:首先,64位的明文经过初始置换(IP)而被重新排列。
然后经历16轮相同函数的作用,每轮作用都有置换和代替。
最后一轮迭代的输出有64位,它是输入明文和密钥的函数。
其左半部分和右半部分互换产生预输出。
最后预输出再被与初始置换(IP)互逆的置换产生64位的密文。
DES算法只不过是加密的两个基本技术——混乱和扩散的组合,即先代替后置换,它基于密钥作用于明文,这是一轮(round),DES在明文分组上实施16轮相同的组合技术。
一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_Table置换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};const static char Final_Table[] = { //最终置换40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25};const static char S_Box[8][64] = { //s_box/* S1 */{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},/* S2 */{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},/* S3 */{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},/* S4 */{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},/* S5 */{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},/* S6 */{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},/* S7 */{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},/* S8 */{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} };const static char Rar_Table[] = { //压缩置换14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32};const static char Exp_Table[] = { //扩展置换32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1};const static char P_Table[]={ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25};const static char KeyRar_Table[]={57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4};//设置全局变量,16轮密钥bool key[16][48]={{0}};void ByteToBit(bool *Out,char *In,int bits) //字节到位转换函数{int i;for(i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8))&1;}void BitToByte(char *Out,bool *In,int bits) //位到字节转换函数{int i;for(i=0;i<bits/8;i++)Out[i]=0;for(i=0;i<bits;i++)Out[i/8]|=In[i]<<(i%8);}void Xor(bool *InA,const bool *InB,int length) //按位异或{for(int i=0;i<length;i++)InA[i]^=InB[i];}void keyfc(char *In) //密钥生成函数{int i,j=0,mov,k,m;bool* key0 = new bool[56];bool* keyin = new bool[64];bool temp;ByteToBit(keyin,In,64); //字节到位的转换for(i=0;i<56;i++) //密钥压缩为56位key0[i]=keyin[KeyRar_Table[i]-1];for(i=0;i<16;i++) //16轮密钥产生{if(i==0||i==1||i==8||i==15)mov=1;elsemov=2;for(k=0;k<mov;k++) //分左右两块循环左移{for(m=0;m<8;m++){temp=key0[m*7];for(j=m*7;j<m*7+7;j++)key0[j]=key0[j+1];key0[m*7+6]=temp;}temp=key0[0];for(m=0;m<27;m++)key0[m]=key0[m+1];key0[27]=temp;temp=key0[28];for(m=28;m<55;m++)key0[m]=key0[m+1];key0[55]=temp;}for(j=0;j<48;j++) //压缩置换并储存key[i][j]=key0[Rar_Table[j]-1];}delete[] key0;delete[] keyin;}void DES(char Out[8],char In[8],bool Type)//加密核心程序,Type=0时加密,反之解密{bool* MW = new bool[64];bool* tmp = new bool[32];bool* PMW = new bool[64];bool* kzmw = new bool[48];bool* keytem = new bool[48];bool* ss = new bool[32];int hang,lie,i;ByteToBit(PMW,In,64);for(int j=0;j<64;j++){MW[j]=PMW[IP_Table[j]-1]; //初始置换}bool *Li=&MW[0],*Ri=&MW[32];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];if(Type==0) //DES加密过程{for(int lun=0;lun<16;lun++){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie =kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3]*2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}else //DES解密过程{for(int lun=15;lun>=0;lun--){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie =kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3]*2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}delete[] MW;delete[] tmp;delete[] PMW;delete[] kzmw;delete[] keytem;delete[] ss;}bool RunDes(char *Out, char *In, int datalength, char *Key, bool Type) //加密运行函数,判断输入以及对输入文本8字节分割{if( !( Out && In && Key && (datalength=(datalength+7)&0xfffffff8) ) )return false;keyfc(Key);for(int i=0,j=datalength%8; i<j; ++i,Out+=8,In+=8)DES(Out, In, Type);return true;}int main(){char* Ki = new char[8];char Enter[]="This is the test of DES!";char* Print = new char[200];int len = sizeof(Enter);int i_mf;cout << "请输入密钥(8位):" <<"\n";for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Print,Enter,len,Ki,0);//加密cout << "----加密前----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << "\n\n";cout << "----加密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout<<Print[i_mf];cout << "\n\n";//此处进行不同密钥输入测试cout << "请输入密钥(8位):" <<"\n";for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Enter,Print,len,Ki,1);//解密cout << "----解密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << endl;delete[] Ki;delete[] Print;return 0;}二、程序编译、运行结果图:三、程序总体框架图:读取待加密文本输入密钥DES 加密显示加密后文本再次输入密钥DES 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:。