网络与信息安全Introduction to Network and Security——DES 加密解密算法的C++实现2011年10月目录一、DES算法的概述 (2)1、DES简介 (2)2、DES算法原理 (2)3、DES算法简述 (3)3.1算法过程的具体分析 (4)3.2 具体示例分析 (7)二、DES算法的C++实现 (8)1、运行环境 (8)2、功能说明 (8)3、程序函数说明 (8)4、程序运行效果图 (19)三、小结 (21)一、DES算法的概述1、DES简介DES是Data Encryption Standard(数据加密标准)的缩写。
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-1DES2-1所示。
从加密公式中能够导出如下的解密过程:⊕f(Li,Ki)图2-1 DES 算法的第i 轮过程3、DES 算法简述DES 算法处理的数据对象是一组64比特的明文串。
设该明文串为m=m1m2…m64 (mi=0或1)。
明文串经过64比特的密钥K 来加密,最后生成长度为64比特的密文E 。
其加密算法过程如图3-1所示下:图3-1算法加密流程图 Li-1 f(Ri-1,Ki)KiLi Ri Ri-13.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所示:对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所示。
在其输入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所示:该比特串分为长度相等的比特串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,因此。
现在考虑第二轮加密。
借助表3-3扩展到R1,得到E(R1)=c0bdf57a570b。
将E(R1)与K2做XOR运算,得到:S32位输出Ω2,因此,Ω2=1ebcebdf。
使用表3-4,计算置换P(Ω2),得到P(Ω2)=5f3e39f7,因此,经过两轮计算后得到的右半部分输出R2=P(ΩL2=R1=85baf2e5在这两轮密码系统中,R2与L2的拼接称作预输出分组。
之后对于输出分组应用表3-7所示的反向置换,这样,第二轮结束后DES算法的输出就成为密文Y:Y=IP^-1(R2||L2)=d7698224283e0aea二、DES算法的C++实现1、运行环境本系统采用Microsoft Visual Studio 2005软件作为开发工具2、功能说明用C++语言实现了DES算法的加密解密过程。
对已输入的明文和密钥进行加密并输出密文;对已输入的密文和密钥进行解密,并输出明文。
3、程序函数说明在本次设计中,具体讲解DES加密和解密程序,并在程序中详细对程序进行了分析,以下是DES加密和解密程序设计的详细过程以及分析说明。
/*源文件:DES.cpp*//*本程序为本人实验程序*/#include <stdio.h>#include <memory.h>#include <string.h>// 初始置换表const static char IP_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_Table。
初始置换在第一轮运算之前执行。
将常量IP_Table看作是一个表结构。
此表应该从左向右读。
例如,初始置换把明文的第58位换到第1位的位置,把第50位换到第2位的位置,把第42位换到第3位的位置。
// 逆初始置换表const static char IPR_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并在一起形成一个分组作为逆初始置换的输入。
其实交换左右两部分并循环移动,仍将获得完全相同的结果。
但这样做,能使该算法既能用作加密,又能用作解密。
// 扩展置换表static const char Extension_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};上面程序主要定义了扩展置换表Extension_Table。
扩展置换将数据的右半部分Ri从32bit扩展到了48bit,这个操作改变了位的次序,重复了某些位。
这样做有两个方面的目的:一是产生了与密钥同长度的数据一进行异或运算:二是提供了更长的结果,使得在替代运算时能进行压缩。