信息安全课程设计——DES 加密与解密
课程设计——DES 算法实现
一、 目的
为了充分的理解 DES 算法的工作原理,实现此算法,这是一种应用比价广泛的算
法,DES 是一种单钥体制,即加密的密钥和解密的密钥是相同的,这里是通过 DES 算
法加密是将明文分组,并记住子密钥,来实现加密和解密的功能的,DES 算法的优点
在于算法简单,密钥不长,而且具有雪崩效应,因为它每次轮转得到的数据需要作为下
一次轮转的输入,而且该过程含有大量的异或运算和置换,所以一个比特出错后面的大
量数据都会出错。
二、 环境
Windows XP 操作系统 VC 集成环境 C 语言
数据结构主要以二维数组为主。
三、 原理与步骤
DES 算法描述:DES 包括加密和解密过程,,但是其加密过程和解密过程的本质是
一样的。 把明文分组,每 64 bit 为一组,为了假单起见,我们假设明文就只有一组,
这号是 64 bit ,这里设明文为 0M =
...mmmm
。
64
3
2
1
对其进行加密过程,其中的运算过程是
L
i
R
i
1
,
R
i
L
i
1
(
KRf
,
1
i
)
i
Feistel是整个加密算法的核心部分。它主要实现f函数的功能(S盒筛选,异或运算P
置换等)。下面是我完成的详细过程。(已知明文为 0M =
(1)IP 置换:首先给明文进行 IP 置换 IP 置换表格已经在算法实现中设置成一个数组,
可参考附录。
IP 置换的主要作用在于打乱明文的顺序,没有特别的含义,。随后将明文分作左右两半
各长 32 bit.。
开始进入迭代
...mmmm
。)
64
3
2
1
(2) 初始子密钥的生成:将已经设定好的子密钥转换成一个长为 64 的数组,然后去掉每
个第 8 位(用于奇偶校验),进行选择 1 置换(置换选择 1 的表格已经在算法中设置成
了一个长为 56 位的数据,参考附录),生成一个长为 56 的数组,也将这个数组分成左
右两部分设为 C0=
ccc
321
...c
28
和 D0=
ddd
2
1
3
...d
28
(3)左移:将得到的这两半数据分别进行左移,最后一位的数据由第一位数据补上,
再将这 56 bit 的数据进行选择 2 置换(置换选择 2 的表格已经在算法中设置成了一个长
为 48 的数组,参考附录)
循环左移的次数如下:
TimesArray[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
每轮可以得到第一个 48 bit 的子密钥记为 1K =
,这就是真正在 f 函数中参
kkk
321
...k
48
与运算的子密钥。
(4)E 扩展:让新的明文的左半边等于当前明文的右半边,并将右半边的数据通过 E 扩展
变换(E 扩展的的表格已经在算法中设置成了一个长为 48 的数组,参考附录)生成一
1
信息安全课程设计——DES 加密与解密
个长尾 48 位的数组,左边暂时包成不变
(5)f 函数的实现:f 函数的功能主要包括异或运算和 S 盒筛选,以及 P 置换。
将子密钥的值与扩张后的 48 bit 数据进行异或运算,得到一个长为 48 bit 的数据,将这
个数据送到 S 盒中进行压缩,将 48 bit 的数据压缩成 32 bit ,将输入 S 盒的 48 位数据每 6
位组成一组数据,共 8 组,正好对应 8 个 S 盒。每组数据的第一位和第六位组成的数据
用来指定对应的 S 盒的行号,中间四位生成的数据用来指定 S 盒的列号。通过对应的行
号和列号,读出 S 盒中的十进制数据,并将其转换为 4 位的 2 进制数,这样就可使结果
存放在一个长为 32 的数组中。将压缩后的数据进行单纯的 P 变换(P 变换的的表格已
经在算法中设置成了一个长为 32 的数组,参考附录),最后让得到的结果与左边的 32 bit
的明文进行异或运算,得到新的明文存在右半边,这样就得到了明文变换后的一组新的
数据,
(6)迭代:就这样从步骤(2)开始迭代 16 次,其目的在于将明文中的数据彻底打乱,得
到 '
...mmmm
16M =
'
64
'
3
'
1
'
2
(7)IP 逆置换:将这 64 bit 数据的左 32 bit 和右 32 bit 数据交换,进行 IP 逆置换(其中
IP 逆变换的的表格已经在算法中设置成了一个长为 48 的数组,参考附录)IP 逆置换和
IP 置换的作用正好是互逆的,没有任何的物理意义,主要是为了将明文打乱。
完成后就得到了我们所需要的密文
cccC
331
...c
64
。
(8)解密:我们必须保存好我们在迭代过程中的的密钥 1K 到 16K ,因为 DES 属于单密
钥体制,必须用相同的密钥才可以对明文进行解密,只对密文加密而不解密的算法显然
是不成功的保密方法。
对于解密过程其实质和加密过成是相同的,只是每次运算的子密钥的顺序和加密的
工程正好相反,例如我们将最后一次迭代的结果左右交换后,传递给解密的初始化数据
0DL 和 0DR 中,故我们有
DL
1
DL
0
L
16
R
15
0
(
DL
f
0
(
KLf
16
(
,
KRf
DR
)
))
16
,
15
16
DR
1
R
16
(
L
15
L
15
,
K
16
)
(
KRf
,
15
)
16
以此类推:有
DL
16
R
,0
DR 。
L
0
16
其实只要清楚 DES 算法中的每个步骤,这个算法的也就变的比较明了了。
四、 结果分析
调试好源码之后,运行程序,输出明文,得到的密文和解密后还原出来的明文,运行结果如
图-1 所示:(为了看出变化,我们还输出了 64 比他的初始明文和最终密文。)
2
信息安全课程设计——DES 加密与解密
下面是 16 次迭代过程中的子密钥:
图-1 明文密文和解密后的明文
我们还可以输出每次迭代过程中的明文左右两半的数据的变化情况,如图-3 所示
图-2 16 次迭代过程中的子密钥的变化
最后我们观察一下 S 盒对应的值的变化,按照理论上说,加密英语解密过程的 S 盒对应的
如图-3 16 次迭代过程中的明文变化情况
3
信息安全课程设计——DES 加密与解密
值应该是想通的只是顺序恰好相反而已,为了方便起见,我们不输出 2 进制值,我们输出 S
盒对应的还没有换算成二进制的十进制的值,程序运行显示的结果如图-4 所示:
图-4 加密解密过程中 S 盒对应值的变化
如图所示,正如我们预言的,解密过程中的每一行 S 盒对应的值都可以在加密过程中找到,
只是所在的顺序不同而已,而且它们的顺序整好相反。
五、 测试数据
给出了 6 组测试数据如下图所示,我分别进行只改变明文,只改变密钥,和分别改变明文和
密钥的操作,原始的明文和密钥是:
maz[8]={50,48,48,55,50,51,55,53};//20072375
ccz[8]={90,79,85,72,69,77,73,78};//Z,O,U,H,E,M,I,N
为了观察醒目,这里还输出了对应的二进制数据,运行结果如下所示:
4
信息安全课程设计——DES 加密与解密
图-5 原始的明文与密钥
图-6 只改变明文 20072375->20092375
图-7 只改变明文 20072375->20082375
图-8 只改变密钥,69->96
图-9 只改变密钥,90->86
图-10 改变明文和密文 20082375->20082375&69->96
5
信息安全课程设计——DES 加密与解密
由上述结果可以看出,DES 算法的敏感度还是很高的,只要改变一点点明文或是密钥,运
行的结果都会有很大的变化,这就是所谓的雪崩效应。
六、 附录
IP[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
};
Z1[56]={ //置换选择 1
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
};
E[48]={
4,
1, 2,
32,
5, 6,
9,
4,
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
};
3,
7,
8,
部分核心代码:
void DToB8(int a[],int b[][8])
{// 将十进制数转换成二进制数
int i=0,r=0,j=0,t=0;
for(j=0;j<8;j++)
{
t=0;
while(*(a+j)!=0)
{
1
IP [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
};
Z2[48]={ //置换选择 2
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
};
P[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
};
r=*(a+j)%2;
*(*(b+j)+(7-t))=r;
*(a+j)/=2;
t++;
}
}
}
6
5,
信息安全课程设计——DES 加密与解密
void IP(int M1[],int M0[])
{// IP 置换
int i;
for(i=0;i<64;i++)
{
M1[i] = M0[IP[i]-1];
}
}
void ReverseIP(int M1[],int M0[])
{// IP 逆置换
int i;
for(i=0;i<64;i++)
{
M1[i]=M0[IP1[i]-1];
}
}
void Expend(int ERL[],int R[][32],int m)
{ //扩展置换
int i;
for(i=0;i<48;i++)
{
ERL[i] = R[m][E[i]-1];
}
}
void Zhihuan1(int C1[],int C0[])
{//置换选择 1
int i;
for(i=0;i<56;i++)
{
C1[i] = C0[Z1[i]-1];
void PChange(int pp[],int sp[])
{//P 置换
for(int i=0;i<32;i++)
pp[i] = sp[P[i]-1];
}
}
}
void Zhihuan2(int SubKey[],int D0[] )
{
//置换选择 2 产生子密钥
int i;
for(i=0;i<48;i++)
{
SubKey[i]=
D0[Z2[i]-1];//C0[0][13];
}
}
void MoveLeft(int C0[][28],int m)
{//左移
int a=0;
int FirstChar;
int i;
while(m--)//MOVE LEFT
{
FirstChar = C0[0][0];
for(i=0;i<27;i++)
{
C0[0][i]=C0[0][i+1];
}
C0[0][27] = FirstChar;
FirstChar = C0[1][0];
for(i=0;i<27;i++)
{
C0[1][i]=C0[1][i+1];
}
C0[1][27] = FirstChar;
}
}
{//异或运算
for(int i=0;i<48;i++)
{
SubKey[i]=ERL[i] ^ SubKey[i];
void Xor1(int SubKey[],int ERL[])
}
}
void BToD8(
{ //二进制转换成十进制
int b[])
7
信息安全课程设计——DES 加密与解密
for(int i=0;i<8;i++)
{
a[i] =b[i*8+7]+b[i*8+6]*2+b[i*8+5]*4+b[i*8+4]*8
+b[i*8+3]*16+b[i*8+2]*32+b[i*8+1]*64+b[i*8+0]*128;
}
}
void SboxChose(int S[],int Key[])
{//S 盒选择
int i=0;
int x,y;
int sp[32]={0};
for(i=0;i<8;i++)
{
x=Key[6*i]*2+Key[6*i+5];
y=Key[6*i+1]*8 + Key[6*i+2]*4 + Key[6*i+3]*2+Key[6*i+4];
S[i] = sbox[i][x][y];
printf("%2d
",S[i]);
DtoB4(sp,S[i],i);
}
PChange(pp,sp);
printf("\n");
}
8