DES分组密码实验报告一、DES算法的实现1.DES简介DES算法工作:如Mode为加密,则用Key去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。2.DES算法详述(1)DES加密标准DES是对二元数字分组加密的分组密码算法,分组长度为64比特。每64位明文加密成64位密文,没有数据压缩和扩展,密钥长度为56比特,若输入64比特,则第8,16,24,32,40,48,56,64为奇偶校验位,所以,实际密钥只有56位。DES算法完全公开,其保密性完全依赖密钥。DES的加密过程可表示为:DES(m)=IP-1T16·T15…T2·T1·IP(m).右图面是完全16轮DES算法框图:图1完全16轮DES算法1初始置换IP初始置换是将输入的64位明文分为8个数组,每一组包括8位,按1至64编号。IP的置换规则如下表:表1IP置换规则585042342618102605244362820124625446383022146645648403224168574941332517915951433527191136153453729211356355473931231572IP-1是IP的逆置换由于第1位经过初始置换后,已处于第40位。逆置换就是再将第40位换回到第1位。逆置换规则如下表所示:表2IP-1置换40848165624643239747155523633138646145422623037545135321612936444125220602835343115119592734242105018582633141949175725初始置换IP及其逆置换IP-1并没有密码学意义,因为置换前后的一一对应关系是已知的。它们的作用在于打乱原来输入明文的ASCⅡ码字划分的关系,并将原来明文的第m8,m16,m24,m32,m40,m48,m56,m64位(校验位)变成IP的输出的一个字节。3.DES算法的迭代过程图中Li-1和Ri-1分别是第i-1次迭代结果的左右两部分,各32比特。即Li=Ri-1,Ri=Li-1f(Ri-1,ki)。其中轮密钥Ki为48比特,函数F(R,K)的计算过程如图所示。轮输入的右半部分R为32比特,R首先被扩展成48比特,扩展过程由表3定义,其中将R的16个比特各重复一次。扩展后的48比特再与子密钥Ki异或,然后再通过一个S盒,产生32比特的输出。该输出再经过一个由表4定义的置换,产生的结果即为函数F(R,K)的输出。3212345表3扩展Eki是由64比特的初始密钥(亦称种子密钥)导出的第i轮子密钥,ki是48比特DES算法的关键是f(Ri-1,ki)的功能,其中的重点又在S-盒(SubstitutionBoxes)上。F函数的输出是32比特。图3F函数计算过程图将R经过一个扩展运算E变为48位,记为E(R)。计算E(R)K=B,对B施行代换S,此代换由8个代换盒组成,即S-盒。每个S-盒有6个输入,4个输出,将B依次分为8组,每组6位,记B=B1B2B3B4B5B6B7B8其中Bj作为第j个S-盒的输入,其输出为Cj,C=C1C2C3C4C5C6C7C8就是代换S的输出,所以代换S是一个48位输入,32位输出的选择压缩运算,将结果C再实行一个置换P(表4),即得F(R,K)。其中,扩展运算E与置换P主要作用是增加算法的扩散效果。S-盒是DES算法中唯一的非线性部件,当然也就是整个算法的安全性所在。它的设计原则与过程一直因为种种不为人知的因素所限,而未被公布出来。S-盒如下表:456789891011121312131415161716171819202120212223242524252627282928293031321表4S-盒函数S11441312151183106125907015741421311061211953841148136211151297310501512824917511314100613S21518146113497213120510313471528141201106911501471110413158126932151381013154211671205149S31009146315511312711428137093461028514121115113649815301112125101471101306987415143115212S47131430691012851112415138115615034721211014910690121171315131452843150610113894511127214S52124171011685315130149141121247131501510398645111101378159125630141181271142136150910453S61211015926801334147511101542712956113140113891415528123704101131164321295151011141760813S74112141508133129751061130117491101435122158614111312371410156805926111381410795015142312S81328461511110931450127115138103741256110149271141912142061013153582114741081315129035611S-盒的置换规则为:取{0,1,…,15}上的4个置换,即它的4个排列排成4行,得一4*16矩阵。若给定该S盒的6个输入为b0b1b2b3b4b5,在Si表中找出b0b5行,b1b2b3b4列的元素,以4位二进制表示该元素,此为S-盒Si的输出。例1S2的输入为101011,b1=1,b6=1,b1b6=(11)2=3(b2b3b4b5)2=(0101)2=5查S2表可知第3行第5列的输出是15,15的二进制表示为1111。则S2的输出为1111。8个S-盒的代换方式都是一样的。S盒输出的32比特经P置换,P置换的功能是将32位的输入,按以下顺序置换,然后输入仍为32比特。P置换的顺序如表5:表5置换P16720212912281711523265183110282414322739191330622114254子密钥的生成初始密钥K(64bit)PC-1C0(28bit)D0(28bit)LS1LS1C1D1LS2LS2LS16LS16C16D16PC-2PC-2K16K1图4DES子密钥生成流程图图4给出了子密钥产生的流程图。首先对初始密钥经过置换PC-1(表2.6[7]),将初始密钥的8个奇偶校验位剔除掉,而留下真正的56比特初始密钥。表3.6密钥置换PC-157494133251791585042342618102595143352719113605244366355473931231576254463830221466153453729211352820124然后将此56位分为C0,D0两部分,各28比特,C0,D0如下:C0=k57k49……k44k36D0=k63k55……k12k4然后分别进行一个循环左移函数LS1,得到C1,D1,将C1(28位),D1(28位)连成56比特数据,再经过密钥置换PC-2(表7)做重排动作,从而便得到了密钥K1(48位)。依次类推,便可得到K2,K3……K16。表7密钥置换PC-21417112415328156211023191242681672720132415231374755304051453348444939563453464250362932其中LS1(1≤i≤16)表示一个或两个位置的循环左移,当i=1,2,9,16时,移一个位置,当i=3,4,5,6,7,8,10,11,12,13,14,15时,移两个位置。(2)DES算法的解密过程DES算法的解密过程跟加密过程是一样的,区别仅仅在于第一次迭代时用密钥k16,第二次k15、……,最后一次用k1,算法本身没有任何变化。二、源代码#includememory.h#includestdio.henum{encrypt,decrypt};//ENCRYPT:加密,DECRYPT:解密voiddes_run(charout[8],charin[8],booltype=encrypt);//设置密钥voiddes_setkey(constcharkey[8]);staticvoidf_func(boolin[32],constboolki[48]);//f函数staticvoids_func(boolout[32],constboolin[48]);//s盒代替//变换staticvoidtransform(bool*out,bool*in,constchar*table,intlen);staticvoidxor(bool*ina,constbool*inb,intlen);//异或staticvoidrotatel(bool*in,intlen,intloop);//循环左移//字节组转换成位组staticvoidbytetobit(bool*out,constchar*in,intbits);//位组转换成字节组staticvoidbittobyte(char*out,constbool*in,intbits);//置换IP表conststaticcharip_table[64]={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};//逆置换IP-1表conststaticcharipr_table[64]={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};//E位选择表staticconstchare_table[48]={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};//P换位表conststaticcharp_table[32]={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};//pc1选位表conststaticcharpc1_table[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,5