題外話:個人覺得DES加密解密真的是一種過程冗長的方法,S盒,P盒還有各種各樣的變換讓人眼花繚亂。
(一)Feistel密碼結構
要先說Feistel密碼結構的原因是DES加密過程是和Feistel密碼結構完全一致的。
Feistel密碼結構首先要將待加密的部分分為左右R0,L0,下一步的操作是將L0不做處理直接傳遞給R1,R0首先要經過一個輪函數F(Rx,Kx)的處理之后再和L0的每一位進行半加操作,一般情況下,在左右兩部分不斷交換的過程中,子密鑰Kx也會不斷地發生變化,實質上是使F(Rx,Kx)函數要進行的操作處理因為Kx的變化而改變。不斷交換的過程也就使明文的統計特性分散到了密文之中,也就是所謂”混淆擴散“,其中輪函數F是整個加密過程中的唯一非線性部分,輪函數的復雜性決定了加密的程度。
代數表達Feistel密碼結構就是:
(二)DES加密過程
DES算法處理的整個過程是將待加密的64bit明文,經過64BIT的密鑰來進行加密,最后生成目標64bit的密文,加密過程具體如下:
1.第一步是從目標的文件或者buffer之中得到將要加密處理的文件指針或者指針,待加密的明文設為如下:
01 02 03 04 05 06 07 08
09 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64
經過IP置換之后形成新的明文序列:(以下b均省略)
58 50 42 34 26 18 10 02
60 52 44 36 28 20 12 04
62 54 46 38 30 22 14 06
64 56 48 40 32 24 16 08
57 49 41 33 25 17 09 01
59 51 43 35 27 19 11 03
61 53 45 37 29 21 13 05
63 55 47 39 31 23 15 07
關於IP置換的具體過程網上的解釋版本真的是很多,但是這並不妨礙我們的DES加密過程,因為將明文IP置換的過程就是一次遍歷明文按索引的過程,我們只需要開出64*sizeof(char)的空間就可以完成初始的IP置換過程。易知在加密過程結束之中我們需要一次IP置換的逆置換(對於矩陣PAA^(-1)=P):
40 08 48 16 56 24 64 32 39 07 47 15 55 23 63 31 38 06 46 14 54 22 62 30 37 05 45 13 53 21 61 29 36 04 44 12 52 20 60 28 35 03 43 11 51 19 59 27 34 02 42 10 50 18 58 26 33 01 41 09 49 17 57 25
2.子密鑰的生成過程
我們最先得到的所謂子密鑰是64bit的,但是其中真正能夠使用到的部分是48位的子密鑰,其中經過了如下一次變換:
(PC-1置換的對應下標矩陣,首先去掉了每行的第8位奇偶校驗位,然后進行置換)
57 49 41 33 25 17 09
01 58 50 42 34 26 18
10 02 59 51 43 35 27
19 11 03 60 52 44 36
-----------------------
63 55 47 39 31 23 15
07 62 54 46 38 30 22
14 06 61 53 45 37 29
21 13 05 28 20 12 04
經過了PC-1置換之后將得到的部分分為前28bit和后28bit分別為C0,D0
然后將C0,D0分別循環移位一位或者兩位,具體的位數由下面這個數列決定
1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1
在DES的十六次迭代過程中,子密鑰的生成過程嚴格按照上述順序進行,如果要將每次循環移位后得到的數據使用到輪函數中作為參數的話,我們需要另一個壓縮置換矩陣PC-2下標矩陣如下:
14 17 11 24 01 05
03 28 15 06 21 10
23 19 12 04 26 08
16 07 27 20 13 02
41 52 31 37 47 55
30 40 51 45 33 48
44 49 39 56 34 53
46 42 50 36 29 32
進行PC-2壓縮置換之后我們得到的是48位的子密鑰,至於怎么用進輪函數之中,下文會有具體介紹。總而言之子密鑰的不斷迭代生成過程可以用如下圖表表示:
3.關於輪函數F(Rx,Kx)內部
首先輪函數接受的參數有兩個一個是待加密的32bit串,另一個是48位的當前迭代輪生成的子密鑰,運算過程如下:
(1)膨脹過程,將32bit的待加密串膨脹為48bit串,這一步也被叫做擴展置換,擴展置換的實質是把32bit串的某些位進行重復出現從而實現擴展,擴展下標表如下所示:
32 01 02 03 04 05
04 05 06 07 08 09
08 09 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 01
這一過程也被稱為“E盒”。之后將通過E盒得到的膨脹后的串和48位的子密鑰進行抑或運算/半加運算,得到一個新48bit串
(2)S盒,這一步也是最關鍵的一步,因為這一步所進行的過程是完全非線性的,也是加密過程中的核心部分。將最新得到的48bit串按順序分為8個6bit的串,每一個6bit通過一個對應的S盒產生一個4位的輸出。具體的過程是這樣的,從6bit串中取第一位和第六位合並合起來作為S盒的行坐標,剩下的四位作為列坐標,例如010111串的第一位是0第六位是1,那么行坐標就是01B列坐標就是1011B即0xB,S盒的每一對坐標都可以得到其中的4位數據如下圖所示:
最后將從8個S盒得到的輸出結果按順序鏈接起來得到一個新的32bit串,再經過一個P盒變換產生一個新的32bit串,P盒變換和E盒變換的過程是相似的,下標矩陣如下:
16 07 20 21
29 12 28 17
01 15 23 26
05 18 31 10
02 08 24 14
32 27 03 09
19 13 30 06
22 11 04 25
這樣的數據從P盒出來就是完成了輪函數的整個過程拉,出來的結果於另半部分合並后再經過16次循環后IP逆置換就得到了密文,下面是我自己繪制的程序框架:
DES算法非常復雜,但是加密程度也非常高,嚴格遵循了雪崩效應 ,使密鑰中一位的改動會導致子密鑰的牽連改變從而完成混淆擴散的目的。
#################################
Problem1:證明DES算法的加密過程是解密過程的逆運算。
Ans:
DES算法遵守Feistel密碼結構,因此有
Ri+1=Li
Li+1=Li⊕F(Ri,Ki)
解密過程中將Ri+1,Li+1代入上述式得(解密左右順序是反的):
Li+1=Ri
Li+1⊕F(Ri,Ki)=Li⊕F(Ri,Ki)⊕F(Li+1,Ki)=Li⊕F(Ri,Ki)⊕F(Ri,Ki)=Li
因此代入后左右兩邊得到的結果是加密過程之中的上一輪的左右部分。