DES加密算法与解密(带流程图)
des加密原理及流程
des加密原理及流程以DES加密原理及流程为标题,本文将详细介绍DES加密算法的原理和加密流程。
DES(Data Encryption Standard)是一种对称加密算法,由IBM 公司于1977年开发。
DES算法是一种分组密码,每个分组64位,密钥长度为56位。
它使用相同的密钥来进行加密和解密操作,因此也被称为对称加密算法。
DES加密算法的原理基于Feistel网络结构。
其主要包括初始置换、16轮的Feistel运算、逆初始置换和密钥生成四个步骤。
首先是初始置换。
明文会经过一个初始置换IP,将64位明文按照固定的规则重新排列,得到L0和R0,每个部分32位。
接下来是16轮的Feistel运算。
每一轮中,将右半部分Rn-1经过扩展置换(E盒),得到48位的扩展结果。
然后将扩展结果与子密钥Kn进行异或运算,得到的结果再经过S盒代替置换,得到32位结果。
最后,通过P盒置换得到Rn。
在Feistel运算中,Ln等于Rn-1,而Rn等于Ln-1异或f(Rn-1, Kn),其中f是一个复杂的函数。
这样,经过16轮的Feistel运算后,得到的L16和R16即为加密的结果。
然后是逆初始置换。
将L16和R16合并,经过逆初始置换IP-1,得到最终的加密结果。
最后是密钥生成。
DES算法使用56位的密钥,其中8位为奇偶校验位。
首先,将64位密钥经过初始置换PC-1,得到56位的密钥。
然后,将56位密钥分为两个28位的部分,分别进行左移位操作,得到C0和D0。
接下来,根据循环左移的规则,生成16个子密钥Ki。
具体地,每轮循环左移的位数由密钥位数表规定,然后将Cn 和Dn合并,经过PC-2置换,得到子密钥Ki。
DES加密算法的流程可以总结为:初始置换、16轮的Feistel运算、逆初始置换和密钥生成。
通过这些步骤,可以将明文加密为密文。
DES加密算法在信息安全领域得到广泛应用。
然而,由于DES密钥长度较短,易受到暴力破解等攻击手段的威胁,因此在实际应用中,常常采用更加安全的加密算法,如AES(Advanced Encryption Standard)来替代DES。
实验2 对称加密算法:DES
实验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加密算法与解密(带流程图)一、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 解密过程为以上逆过程。
DES和AES算法详解
DES和AES算法详解DESDES简介数据加密标准(DES,Data Encryption Standard)是一种使用密钥加密的块密码,1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开来。
它基于使用56位密钥的对称算法。
这个算法因为包含一些机密设计元素,相对短的密钥长度以及怀疑内含美国国家安全局(NSA)的后门而在开始时有争议,因此DES因此受到了强烈的学院派式的审查,并以此推动了现代的块密码及其密码分析的发展。
DES是一种分组密码,明文、密文和密钥的分组长度都是64位,并且都是面向二进制的密码算法。
DES处理的明文分组长度为64位,密文分组长度也是64位,使用的密钥长度为56位(实现上函数要求一个64位的密钥作为输入,但其中用到的只有56位,另外8位可以用作奇偶校验位或者其他用途)。
DES的解密过程和加密相似,解密时使用与加密同样的算法,不过子密钥的使用次序要反过来。
DES的整个体制是公开的,系统的安全性完全靠密钥的保密。
DES算法概述DES算法框图:子密钥产生过程:算法主要包括:初始置换IP、16轮迭代的乘积变换、逆初始置换IP-1以及16个子密钥产生器。
DES算法详解密钥的产生DES的乘积变换部分含有16轮非线性变换,每一轮变换都用一个48比特的子密钥,共需16个不同的48比特的子密钥。
一个64比特的外部密钥经过密钥产生器产生48比特的16个子密钥。
置换1:置换1的作用是将56比特密钥K’各位上的数按规定方式进行换位。
置换后的56比特分别存到两个28比特的寄存器中。
如图:C0的各位依次为原密钥中的57,49,41,…,36位,D0的各位依次为原密钥中的63,55,…,4位。
循环左移寄存器:每个循环左移寄存器都有28比特,加密时,循环寄存器对C(i+1)、D(i+1)的内容是将循环寄存器对C(i)、D(i)的内容分别左移1至2位得到的。
各级寄存器移位的比特数如表所示:压缩置换:是从56位内容中选出48位,产生16轮加密的16子密钥。
数据加密标准DES
数据加密标准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算法一、DES算法DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM 公司研制的对称密码体制加密算法。
明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。
DES工作的基本原理是,其入口参数有三个:key、data、mode。
key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。
当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。
实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,整个算法的主流程图如下:其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则见下表: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,即将输入的第58位换到第一位,第50位换到第2位,...,依此类推,最后一位是原来的第7位。
L0、R0则是换位输出后的两部分,L0是输出的左32位,R0 是右32位,例:设置换前的输入值为D1D2D3......D64,则经过初始置换后的结果为:L0=D58D50...D8;R0=D57D49 (7)经过16次迭代运算后。
DES的加密解密流程
Feistel 结构图
Feistel结构定义 Feistel结构定义
• 加密: Li = Ri-1; Ri = Li-1⊕F(Ri-1,Ki) • 解密: Ri-1 = Li Li-1 = Ri⊕F(Ri-1,Ki) = Ri⊕F(Li,Ki)
Feistel 的加密 和解密
DES算法的基本结构
置换表(P表)
子密钥的产生
置换选择1
置换选择2和循环左移次数
初始置换(IP)
逆初始置换(IP-1)
DES每轮变换 Li = Ri-1 Ri = Li-1⊕F(Ri-1,Ki) ⊕
F函数
Expansion: 32 S-box: 6 4 Permutation 48
扩展/置换表(ox)
S盒(S-box)(续)
S盒(S-box)(续)
DES加解密算法的实例
DES加解密算法的实例DES(Data Encryption Standard)是一种对称密钥加密算法,由IBM于1977年开发。
它是最早广泛使用且被接受的加密算法之一,被用于许多领域,如金融、电子商务和电子邮件等。
DES算法的基本操作单元是64位的数据块,它使用一个56位的密钥对数据进行加密和解密。
下面将对DES算法的加密和解密过程进行详细说明。
1.密钥生成:DES算法使用的密钥是56位的,由8个字节构成。
然而,为了增强安全性和抵抗暴力破解,通常将密钥扩展为64位,即每个字节的最高位被视为奇偶校验位。
密钥生成过程将密钥扩展到64位,并生成16个子密钥。
2.初始置换(IP置换):加密过程开始前,明文数据块会被进行初始置换。
这个初始置换步骤的目的是打乱明文的比特位,使其在加密过程中更难以分析。
3. 轮函数(Feistel函数):DES算法使用了16个相同的轮函数,每个轮函数包含以下步骤:a.扩展置换(E-置换):将32位的数据扩展为48位。
b.异或操作:将扩展得到的48位数据与一个子密钥进行异或操作。
c.S-盒替换:将异或结果分为8个6位的子块,每个子块经过一个6×4的S盒代替变换。
d.P-置换:将S盒代替变换后的结果进行置换操作。
e.得到一个32位的数据。
4.加解密:加密和解密过程中,轮函数通过迭代应用于数据块。
在加密过程中,子密钥按照顺序应用于轮函数;而在解密过程中,子密钥的应用次序与加密过程相反。
DES算法采用了16轮迭代,每轮迭代后,加解密都会进行部分结果的异或操作。
5.逆初始置换(IP-1置换):在加密或解密过程的最后,最终得到的数据块需要进行逆初始置换。
这个逆初始置换的目的是撤销初始置换操作,使得结果与初始的明文或密文一致。
DES算法的实例:1.加密过程:c.将64位的密钥扩展为56位并生成子密钥。
e.经过逆初始置换,得到最终加密的密文。
2.解密过程:a.经过逆初始置换,得到初始的密文数据块。
DES算法详解
DES算法详解简介 DES(Data Encryption Standard)数据加密标准。
DES是有IBM公司研制的⼀种对称加密算法,美国国家标准局于1977年公布把它作为⾮机要部门使⽤的数据加密标准。
DES是⼀个分组加密算法,就是将明⽂分组进⾏加密,每次按顺序取明⽂⼀部分,⼀个典型的DES以64位为分组,加密解密⽤算法相同。
它的密钥长度为56位,因为每组第8位是⽤来做奇偶校验,密钥可以是任意56位的数,保密性依赖于密钥。
概念 1、密钥:8个字节共64位的⼯作密钥(决定保密性能) 2、明⽂:8个字节共64位的需要被加密的数据 3、密⽂:8个字节共64位的需要被解密的数据加解密过程加密 1、明⽂数据分组,64位⼀组。
2、对每组数据进⾏初始置换。
即将输⼊的64位明⽂的第1位置换到第40位,第2位置换到第8位,第3位置换到第48位。
以此类推,最后⼀位是原来的第7位。
置换规则是规定的。
L0(Left)是置换后的数据的前32位,R0(Right)是置换后的数据的后32位; 具体置换规则有四步: 第⼀步:将明⽂数据转换为16*4的⼆维数组,形成⼀个数据空间。
第⼆步:数据左右对分,变成两个16*2的⼆维数组,然后每个数组各⾃都需要这样操作:从下往上,每两⾏形成⼀⾏数据。
分别得到两个8*4的⼆维数组。
第三步:新建⼀个16*4的⼆维数组(strNew1[16][4]),数组上半部分空间的数据存储左边数据块置换的结果,下半部分存储右边数据库置换的结果。
最后⼀步:把整个(strNew1[16][4])16*4的⼆维数组数据空间的按列进⾏置换到新的⼆维数组(strNew2[16][4]): 数组strNew1第2列放到数组strNew2第1列的位置; 数组strNew1第4列放到数组strNew2第2列的位置; 数组strNew1第1列放到数组strNew2第3列的位置; 数组strNew1第3列放到数组strNew2第4列的位置; 数组strNew2就是我们初始置换的结果。
des算法原理
des算法原理
DES(Data Encryption Standard)算法是一种对称密钥加密算法,其原理是通过将输入的明文分为64位的数据块,并使用
56位的密钥进行加密算法的运算,产生64位的加密结果。
其中,密钥需要经过一系列的处理、置换和代换操作,生成16
个子密钥,用于加密和解密过程。
DES算法的具体步骤如下:
1. 初始置换(IP):将输入的64位明文按照固定的置换表进
行重排,得到一个新的64位数据。
2. 密钥生成:首先将输入的56位密钥按照固定的表格进行重
排和压缩,生成两个28位的子密钥。
接下来,通过循环左移
操作和再次压缩生成16个48位的子密钥。
3. 加密过程:将初始置换得到的64位数据分为左右两部分,
每部分32位。
通过16轮的迭代运算,每轮运用不同的子密钥,进行数据的替换、扩展、异或和代换,最终生成新的数据。
4. 逆初始置换(IP-1):将经过16轮迭代运算得到的数据按
照逆序的置换表进行重排,得到最终的加密结果,即64位密文。
DES算法的安全性主要依赖于密钥的长度和子密钥的生成过程。
但是由于DES算法使用的56位密钥相对较短,且经过逐
轮迭代,密文的影响主要依赖于前面轮次的加密结果,因此DES算法的安全性逐渐被破解。
为此,后续的算法如3DES和
AES(Advanced Encryption Standard)的出现取代了DES算法,以提供更高的安全性。
DES的加密与解密算法(Python实现)
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加密算法原理与实现DES算法简介DES(Data Encryption Standard)是⽬前最为流⾏的加密算法之⼀。
DES是对称的,也就是说它使⽤同⼀个密钥来加密和解密数据。
DES还是⼀种分组加密算法,该算法每次处理固定长度的数据段,称之为分组。
DES分组的⼤⼩是64位,如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。
从本质上来说,DES的安全性依赖于虚假表象,从密码学的术语来讲就是依赖于“混乱和扩散”的原则。
混乱的⽬的是为隐藏任何明⽂同密⽂、或者密钥之间的关系,⽽扩散的⽬的是使明⽂中的有效位和密钥⼀起组成尽可能多的密⽂。
两者结合到⼀起就使得安全性变得相对较⾼。
DES算法具体通过对明⽂进⾏⼀系列的排列和替换操作来将其加密。
过程的关键就是从给定的初始密钥中得到16个⼦密钥的函数。
要加密⼀组明⽂,每个⼦密钥按照顺序(1-16)以⼀系列的位操作施加于数据上,每个⼦密钥⼀次,⼀共重复16次。
每⼀次迭代称之为⼀轮。
要对密⽂进⾏解密可以采⽤同样的步骤,只是⼦密钥是按照逆向的顺序(16-1)对密⽂进⾏处理。
计算16个⼦密钥上⾯提到DES算法的第⼀步就是从初始密钥中计算得出16个⼦密钥。
图⽰1展⽰了这个过程。
DES使⽤⼀个56位的初始密钥,但是这⾥提供的是⼀个64位的值,这是因为在硬件实现中每8位可以⽤于奇偶校验,在软件实现中多出的位只是简单的忽略掉。
要获得⼀个56位的密钥,可以执照表1的⽅式执⾏密钥转换。
解释⼀下表1,按照从左往右从上往下的⽅式看,表格中每个位置P包含初始密钥中位在转换后的密钥中所占的位置。
⽐如,初始密钥中的第57位就是转换后的密钥中的第1位,⽽初始密钥中的第49位则变成转换后的密钥中的第2位,以此类推...。
(数据位的计数顺序按照从左到右从1开始的)表1:DES中密钥的转换表(DesTransform[56])将密钥转换为56位后,接下来计算⼦密钥。
DES算法详解
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(一)
计算机⽹络安全——对称加密算法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加密算法与解密(带流程图)
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加密解密算法的实现
DES加密解密算法的实现DES(Data Encryption Standard)是一种对称加密算法,用于加密和解密数据。
其基本原理是通过使用密钥将明文数据转换为密文数据,并使用相同的密钥将密文数据还原为明文数据。
DES算法采用了分组加密的方式,将明文数据分为固定大小的数据块,并对每个数据块进行加密。
DES算法的实现包括了三个主要步骤:初始置换、16轮迭代加密和最终置换。
下面将详细介绍DES加密解密算法的实现步骤。
1. 初始置换(Initial Permutation):初始置换是将明文数据进行重排,以增加加密的随机性。
它通过将明文数据按照规定的顺序排列成新的数据,作为加密的初始输入。
2. 16轮迭代加密(16 Rounds of Iterative Encryption):DES算法将明文数据进行16轮的迭代加密。
每一轮加密包括了四个主要步骤:逐位扩展(Expansion Permutation)、密钥混淆(Key Mixing)、S盒替代和P盒置换。
- 逐位扩展(Expansion Permutation):逐位扩展将32位的数据扩展为48位的数据,以提供更高的密钥强度,并增加加密的随机性。
- 密钥混淆(Key Mixing):密钥混淆是将48位的数据与密钥进行异或运算,以增加加密的复杂性。
- S盒替代(S-Box Substitution):S盒替代是将48位的数据分成8个6位的数据块,并根据S盒中预先定义的替代规则进行替代。
S盒替代是DES算法的核心步骤,它对密文数据进行非线性转换,增加了加密的强度。
- P盒置换(P-Box Permutation):P盒置换是将32位的数据按照规定的顺序进行重排,以增加加密的随机性。
3. 最终置换(Final Permutation):最终置换是将经过16轮迭代加密后的数据进行一个最终的变换,以得到加密的最终输出。
最终置换和初始置换相反,将经过加密处理的数据重新排列成最终输出。
DES加密解密算法
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位,...... 以此类推。
DES加解密过程和实现
********************本科生作业********************兰州理工大学计算机与通信学院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加密与解密过程原理解析
网络与信息安全作业题目: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位。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_T able置换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,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,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_T able[]={ //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_T able[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];}}{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盒置换*/{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 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:。