DES加密算法详解及C++实现

DES对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是一样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码),是一种对称加密算法。这是一个迭代分组密码,使用称为 Feistel 的技术,其中将加密的文本块分红两半。使用子密钥对其中一半应用循环功能,而后将输出与另外一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操做四种基本运算。算法

0x00 DES 的基本原理

1.入口参数

key:加密解密使用的密钥。64位,包括56位的密钥及8位奇偶校验位(第8i位,i=1,2 ··· 8)app

data:加密解密的数据。64位函数

mode:工做模式。加密模式、解密模式加密

2.初始IP置换

使用初始IP置换该版本64bits明文中各位的排列顺序,IP置换表以下:spa

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位移至第一位······以此类推。.net

将变换后的明文分红左右两份,各32bits,称之为L0,R03d

3.生成子密钥

将64bits的密钥key去除奇偶校验位,剩下的56位按以下密钥置换表进行置换:code

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

相似的,将变换后的56bits密钥分红左右两份,各28bits,称之为C0,D0blog

而后对C0与D0分别进行16轮循环左移,每轮移动的位数参照下表,便可生成C1,C2 ··· C16;D1,D2 ··· D16ci

每轮循环密钥位移动的位数
循环轮数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
移位 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1

将每轮的Ci,Di合并在一块儿造成56bits的字串,再按照以下压缩置换表进行置换,便可将56bits压缩至48bits的子密钥Ki

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

一共16轮移位,也就生成了K1,K2 ··· K16,16个子密钥

4.迭代加密

迭代加密共计16轮,对于1 <= i <= 16,执行以下操做:

L_{i} = R_{i-1}

R_{i} = L_{i-1} \bigoplus f(R_{i-1} , K_{i} )

其中Li与Ri是第i轮加密后获得的值,其初始值就是上面的L0与R0。Ki没必要多说,就是上面的子密钥,那么如今只剩下函数f()是未知的,下面就对函数 f(Ri,Ki)进行分析。

DES

(1)咱们知道,Ri是32bits的,而Ki是48bits,做为一个函数的两个参数貌似不太搭的样子,那么函数首先要作的就是将R扩展成48bits。上面压缩子密钥的时候用的是压缩置换表,那么如今要扩展,固然要上扩展置换表啦,仔细看看这个表其实还挺有规律,中间4列就是顺序排列的32bits。把通过置换的R称之为E(R)

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

(2)E(R)和Ki长度相同了,整个按位异或,二合一岂不美哉,异或后结果还是48bits,记做B1,B2 ··· B8,每一个Bi有6bits。

(3)最烦的一步,8个S盒,S1,S2 ··· S8,每一个S盒4行16列。将上一步的Bj做为Sj的输入。Bj有6bits,于时将Bj记做Bj = b1b2b3b4b5b6,其中b1b6肯定S盒的行号,b2b3b4b5肯定列号。例如,B1=100100,则b1b6=10=3,即选中第三行,b2b3b4b5=0010=2,即选中第2列,S1的第三行第二列的值是1,于时输出1的二进制0001。上面说了有8个Bj,8个S盒,那么就有8个4位二进制的输出,将其记做C1,C2 ··· C8。

// S盒1
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,

// S盒2
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,

// S盒3
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,

// S盒4
 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,

// S盒5
 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,

// S盒6
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,

// S盒7
 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,
 
// S盒8
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

(4)其实DES中除了S盒,还有个P盒,经历了S盒的洗礼,感受P盒是这么的清新简约。将上面获得的C1,C2 ··· C8连成一串,总共32bits,再通过下面的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

以上就是函数 f(Ri,Ki)的所有过程了,通过置换获得的32bits,就是f(Ri,Ki)。

5.逆初始置换

还记得咱们一开始作了个初始置换,那么最后一步就是进行它的逆置换,把最后一轮加密获得的L16与R16连在一块儿,再通过逆置换,终于获得了最终的密文

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

0x01 DES的C++实现

代码太长,另写了一篇

http://www.javashuo.com/article/p-ojwlsogz-nc.html

0x02 参考文献

[1]  百度百科 DES对称加密

[2] [美]Wade Trappe,Lawrence C.Washington:《密码学概论》,邹红霞等译,人民邮电出版社2004-1版

[3] 一位大佬的博客