网络与信息安全IntroductiontoNetworkandSecurity——DES加密解密算法的C++实现2011年10月1目录一、DES算法的概述.......................................................................21、DES简介.................................................................................22、DES算法原理.........................................................................23、DES算法简述.........................................................................33.1算法过程的具体分析......................................................43.2具体示例分析.................................................................7二、DES算法的C++实现...............................................................81、运行环境................................................................................82、功能说明................................................................................83、程序函数说明........................................................................84、程序运行效果图..................................................................19三、小结..........................................................................................212一、DES算法的概述1、DES简介DES是DataEncryptionStandard(数据加密标准)的缩写。1974年,IBM向NBS提交了由Tuchman博士领导的小组设计并经改造的Luciffer算法。NSA(美国国家安全局)组织专家对该算法进行了鉴定,使其成为DES的基础。1975年NBS公布了这个算法,并说明要以它作为联邦信息加密标准,征求各方意见。1976年,DES被采纳作为联邦标准,并授权在非机密的政府通信中使用。DES在银行,金融界崭露头角,随后得到广泛应用。几十年过去了,虽然DES已不再作为数据加密标准,但它仍然值得研究和学习。首先三重算法仍在Internet中广泛使用,如PGP和S/MIME中都使用了三重DES作为加密算法。其次,DES是历史上最为成功的一种分组密码算法,它的使用时间之长,范围之大,是其它分组密码算法不能企及的,而DES的成功则归因于其精巧的设计和结构。2、DES算法原理DES是一个对称分组密码,它使用56位密钥操作64位分组。DES以64位分组形式加密数据。算法的输入是64位分组的明文,算法的输出是64位分组的密文,明文到密文经过了16轮一致的运算。通过剔除8个奇偶校验位,即忽略给定64位密钥中的每一个第8位,从而得到密钥长度为56位。与其他分组加密方案一样,加密函数使用了两个输入:要被加密的64位明文和56位密钥。DES的基本构建是对明文分组的进行置换和替换的适宜组合(16次)。通过S-盒查表完成替换。除了以相反次序处理密钥次序表之外,加密和解密使用了相同的算法。明文分组X组首先按初始置换IP表进行置换,得到Xo=IP(X)=(Lo,Ro)。经过16轮的置换、XOR和替换之后,反向置换IP^-1生成密文分组。如果使用Xi=(Li,Ri)表示第i轮加密结果,那么有:Li=Ri-1Ri=Li-1⊕f(Ri-1,Ki)DES的第i轮加密如图2-1所示。从加密公式中能够导出如下的解密过程:Ri-1=LiLi-1=Ri⊕f(Ri-1,Ki)=Ri⊕f(Li,Ki)3图2-1DES算法的第i轮过程3、DES算法简述DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64(mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密算法过程如图3-1所示下:图3-1算法加密流程图Li-1f(Ri-1,Ki)KiLiRiRi-1143.1算法过程的具体分析①IP置换对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如表3-1下:该比特串被分为32位的Lo和32位的Ro两部分。Ro子密钥K1(子密钥的生成将在后面讲)经过变换f(Ro,K1)(f变换将在下面讲)输出32位的比特串f1,f1与Lo做不进位的二进制加法运算。运算规则为:f1与Lo做不进位的二进制加法运算后的结果赋给R1,Ro则原封不动的赋给L1。L1与Ro又做与以上完全相同的运算,生成L2,R2……一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1后所得比特串的下标列表3-2如下:经过置换IP-1后生成的比特串就是密文。②变换f(Ri-1,Ki)的功能它的功能是将32比特的输入再转化为32比特的输出。其过程如图3-2所示:5对f变换说明如下:输入Ri-1(32比特)经过变换E后,膨胀为48比特。膨胀后的比特串的下标列表3-3如下:膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换后,其下标列表3-4如下:经过P变换后输出的比特串才是32比特的f(Ri-1,Ki)。③S盒的变换过程任取一S盒。见图3-3所示。6在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6,y=b5+b4*2+b3*4+b2*8,再从Si表中查出x行,y列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图3-4所示)④子密钥的生成64比特的密钥生成16个48比特的子密钥。子密钥生成过程具体解释如下:64比特的密钥K,经过PC-1后,生成56比特的串。其下标如表3-5所示:7该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表3-6为:C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。注意:Lsi(I=1,2,….16)的数值是不同的。具体见下表:3.2具体示例分析假设64位明文为X=3570e2f1ba4682c7,密钥K=581fbc94d3a452ea,包括8个奇偶校验位,前2轮的密钥分别是K1=27a169e58dda和K2=da91ddd76748。出于演示的目的,这里的DES加密限制为仅仅使用的前两轮情况。使用表3-4IP将明文X划分为两个分组(Lo,Ro),这样,Lo=ae1ba189和Ro=dc1f104。32位的Ro被扩展为48位E(Ro),这样,E(Ro)=6f80fe8a17a9。通过E(Ro)与第一轮的密钥K1进行XOR运算,得到密钥依赖函数f1,这样:f1=E(Ro)K1=4821976f9a73这个48位的f1首先被划分为8个6位分组,之后供给8个Si盒。从S盒替换阶段得到计算输出结果为Ω1=a1ec961c。利用表3-5,Ω1的置换位置为P(Ω1)=2吧536c。将P(Ω1)与Lo作模2加,得到:R1=P(Ω1)Lo=85baf2e5由此L1=Ro,因此L1=dc1f10f4。现在考虑第二轮加密。借助表3-3扩展到R1,得到E(R1)=c0bdf57a570b。8将E(R1)与K2做XOR运算,得到:f2=E(R1)K2=1a2c28ade043S盒的替换操作得到32位输出Ω2,因此,Ω2=1ebcebdf。使用表3-4,计算置换P(Ω2),得到P(Ω2)=5f3e39f7,因此,经过两轮计算后得到的右半部分输出R2=P(Ω2)L1=83212903第二轮计算后的左半部分输出立刻可以得到:L2=R1=85baf2e5在这两轮密码系统中,R2与L2的拼接称作预输出分组。之后对于输出分组应用表3-7所示的反向置换,这样,第二轮结束后DES算法的输出就成为密文Y:Y=IP^-1(R2||L2)=d7698224283e0aea二、DES算法的C++实现1、运行环境本系统采用MicrosoftVisualStudio2005软件作为开发工具2、功能说明用C++语言实现了DES算法的加密解密过程。对已输入的明文和密钥进行加密并输出密文;对已输入的密文和密钥进行解密,并输出明文。3、程序函数说明在本次设计中,具体讲解DES加密和解密程序,并在程序中详细对程序进行了分析,以下是DES加密和解密程序设计的详细过程以及分析说明。/*源文件:DES.cpp*//*本程序为本人实验程序*/#includestdio.h#includememory.h#includestring.h//初始置换表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,957,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_Table。初始置换在第一轮运算之前执行。将常量IP_Table看作是一个表结构。此表应该从左向右读。例如,初始置换把明文的第58位换到第1位的位置,把第50位换到第2位的位置,把第42位换到第3位的位置。//逆初始置换表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};上面程序主要定义了逆初始置换表IPR_Table。逆初始置换是初始置换的逆过程。注意,DES在最后一轮后,左半部分和右半部分并未交换,而是R16和L16并在一起形成一个分组作为逆初始置换的输入。其实交换左右两部分并循环移动,仍将获得完全相同的结果。但这样做,能使该算法既能用作加密,又能用作解密。//扩展置换表staticconstcharExtension_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,