DES加密算法介紹(含例子)


http://www.hankcs.com/security/des-algorithm-illustrated.html

DES(Data Encryption Standard)算法是世界上最常用的加密算法。在很長時間內,許多人心目中“密碼生成”與DES一直是個同義詞。

DES是怎么工作的?本文通過一個簡單的例子來一部一部展示DES的加密流程。自動DES誕生以來,許多加密算法都采用了類似DES的手段。一旦理解了DES中的變換,你一定能夠更輕松的理解這些現代加密算法中的門道。

 

DES處理比特,或者說二進制數字,我們知道,沒四個比特構成一個十六進制數。DES加密一組64位的信息,也就是16個16進制數。為了完成加密,DES

 

DES秘鑰獲取:

我們取16進制秘鑰K為:

K = 133457799BBCDFF1

我們可以得到他的二進制形式(1為0001,3為0011,依次類推,並且將沒8位寫成一組。這樣每組的最后一位都沒有被用上。)

K = 00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001

創建16個子秘鑰,每個長48比特

這個64位的秘鑰首先根據表格PC-1進行變換。

表PC-1

PC-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

 由於上表中第一個元素為57,這將使元秘鑰的第57位變換為新秘鑰K+的第一位。同理,元秘鑰的第49位變換為新秘鑰的第2位,,,元秘鑰的第4位變換為新秘鑰的最后一位,注意元秘鑰中只有56位會進入新秘鑰,上表也只有56個元素。

比如,對於原秘鑰:

K = 00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001

我們將得到56位新秘鑰:

K+ = 1111000 0110011 0010101 0101111 0101010 1011001 1001111 0001111

然后,我們將這個密鑰拆分為左右兩個部分,C0和D0,每半邊都有28位。

比如,對於新密鑰,我們得到:

C0 = 1111000 0110011 0010101 0101111 
D0 = 0101010 1011001 1001111 0001111

對於相同定義的C0和D0,我們現在創建16個塊Cn和Dn 1<=n<=16.

每一對Cn和Dn都是由前一對Cn-1和Dn-1移位而來。具體來說,對於n=1,2,3,。。。,16,在前一輪移位的結果上,進行左移操作。什么叫左移?左移指的是將除第一位外的所有為往左移一位,將第一位移動至最后一位。

這意味着,比如說,C3和D3是C2和D2移位而來的,具體來說,通過2次左移位,C16和D16則是由C15和D15通過1次左移得到的。在所有情況下,一次左移就是將所有比特往左移動一位。使的一位后的比特的位置相較於變換前成為2,3,4,,,28,1.

比如,對於原始字謎要C0和D0,我們得到:

C0 = 1111000011001100101010101111
C1 = 1110000110011001010101011111
C2 = 1100001100110010101010111111
C3 = 0000110011001010101011111111
C4 = 0011001100101010101111111100
C5 = 1100110010101010111111110000
C6 = 0011001010101011111111000011
C7 = 1100101010101111111100001100
C8 = 0010101010111111110000110011
C9 = 0101010101111111100001100110
C10 = 0101010111111110000110011001
C11 = 0101011111111000011001100101
C12 = 0101111111100001100110010101
C13 = 0111111110000110011001010101
C14 = 1111111000011001100101010101
C15 = 1111100001100110010101010111
C16 = 1111000011001100101010101111
D0 = 0101010101100110011110001111
D1 = 1010101011001100111100011110
D2 = 0101010110011001111000111101
D3 = 0101011001100111100011110101
D4 = 0101100110011110001111010101
D5 = 0110011001111000111101010101
D6 = 1001100111100011110101010101
D7 = 0110011110001111010101010110
D8 = 1001111000111101010101011001
D9 = 0011110001111010101010110011
D10 = 1111000111101010101011001100
D11 = 1100011110101010101100110011
D12 = 0001111010101010110011001111
D13 = 0111101010101011001100111100
D14 = 1110101010101100110011110001
D15 = 1010101010110011001111000111
D16 = 0101010101100110011110001111

我們現在就可以得到第n輪的新秘鑰Kn(1<=n<=16)了。具體做法是,對每一對拼合后的子秘鑰CnDn,按照表PC-2執行變換:

PC-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

 

每對子秘鑰有56位,但是PC-2僅僅使用其中48位。

於是,第你輪新秘鑰Kn的第一位來自組合秘鑰CnDn的第14位,第2位來自第17位,以此類推,知道新秘鑰的第48位來自組合秘鑰的第32位。

比如:

對於第一輪的組合秘鑰,我們有:

C1D1 = 1110000 1100110 0101010 1011111 1010101 0110011 0011110 0011110

通過PC-2的變換后,得到:

K1 = 000110 110000 001011 101111 111111 000111 000001 110010

同理,對於其他秘鑰,我們得到:

K2 = 011110 011010 111011 011001 110110 111100 100111 100101
K3 = 010101 011111 110010 001010 010000 101100 111110 011001
K4 = 011100 101010 110111 010110 110110 110011 010100 011101
K5 = 011111 001110 110000 000111 111010 110101 001110 101000
K6 = 011000 111010 010100 111110 010100 000111 101100 101111
K7 = 111011 001000 010010 110111 111101 100001 100010 111100
K8 = 111101 111000 101000 111010 110000 010011 101111 111011
K9 = 111000 001101 101111 101011 111011 011110 011110 000001
K10 = 101100 011111 001101 000111 101110 100100 011001 001111
K11 = 001000 010101 111111 010011 110111 101101 001110 000110
K12 = 011101 010111 000111 110101 100101 000110 011111 101001
K13 = 100101 111100 010111 010001 111110 101011 101001 000001
K14 = 010111 110100 001110 110111 111100 101110 011100 111010
K15 = 101111 111001 000110 001101 001111 010011 111100 001010
K16 = 110010 110011 110110 001011 000011 100001 011111 110101

關於子秘鑰的話題我們就到此為止,接下來我們看信息本身。

 

DES是一個基於組塊的加密算法,這意味着無論輸入還是輸出都是64位長度。也就是說DES產生了一種最多264中的變換方法。每個64位的區塊被分為2個32位的部分,左半部分L和右半部分R。

比如明文,M為

M = 0123456789ABCDEF

這里的M是16進制的,將M寫成二進制,我們得到一個64位的區塊:

M = 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
L = 0000 0001 0010 0011 0100 0101 0110 0111
R = 1000 1001 1010 1011 1100 1101 1110 1111

M的第一位是0,最后一位是1,我們從左讀到右。

 

對於明文M,我們計算一下初始變換IP(Initial permutation)。IP是重新變換數據M的每一位產生的。產生過程由下表決定,表格的下標對應新數據的下標,表格的數值x表示新數據的這一位來自舊數據的第x位。

比如,對M的區塊,執行初始變換,得到:

M = 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
IP = 1100 1100 0000 0000 1100 1100 1111 1111 1111 0000 1010 1010 1111 0000 1010 1010

接着講變換IP分為32位的左半邊L0和右半邊R0

比如,對於上例,我們得到:

L0 = 1100 1100 0000 0000 1100 1100 1111 1111 
R0 = 1111 0000 1010 1010 1111 0000 1010 1010

 

我們接着執行16個迭代,對1<=n<=16,使用一個函數f.函數f輸入兩個區塊,一個32位的數據塊和一個48位的木曜區塊Kn,輸出一個32位的區塊。定義+表示異或XOR。那么讓n從1循環到16,我們計算:

Ln=Rn-1

Rn=Ln-1+f(Rn-1,Kn)

這樣我們就得到最終區塊,也就是n=16的L16R16.這個過程說白了就是,我們那前一個迭代結果的右邊32位作為當前迭代的左邊32位。對於當前迭代的右邊32位,將它和上一個迭代的f函數的輸出執行XOR運算。

比如,對於n=1,我們有:

K1 = 000110 110000 001011 101111 111111 000111 000001 110010 
L1 = R0 = 1111 0000 1010 1010 1111 0000 1010 1010 
R1 = L0 + f(R0,K1)

剩下就是f函數是如何工作的了,為了計算f,我們首先擴展每個Rn-1,將其從32位擴展到48位,這是通過使用一張表來重復Rn-1中的一位位來實現的。我們稱這個過程為函數E。也就是說函數E(Rn-1)輸入32位輸出48位。

 

定義E為函數E的輸出,將其寫成8組,每組6位,這些比特是通過選擇輸入的某些位來產的,具體選擇順序按照如下表格實現:

E BIT-SELECTION TABLE
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

也就是說E(Rn-1)開頭的三個比特分別來自Rn-1的第32、1和2位。E(Rn-1)末尾的2個比特分別來自Rn-1的第32位和第1位。

比如:給定R0,我們可以計算出E(R0):

R0 = 1111 0000 1010 1010 1111 0000 1010 1010 
E(R0) = 011110 100001 010101 010101 011110 100001 010101 010101

接着在f函數中,我們對輸出E(Rn-1)和秘鑰Kn執行XOR運算:

Kn+E(Rn-1)

比如,對K1,E(R0),我們有:

K1 = 000110 110000 001011 101111 111111 000111 000001 110010 
E(R0) = 011110 100001 010101 010101 011110 100001 010101 010101 
K1+E(R0) = 011000 010001 011110 111010 100001 100110 010100 100111

到這里我們還沒有完成f函數的運算,我們僅僅使用一張表將Rn-1從32位擴展為48位,並且對這個結果和秘鑰Kn執行了異或運算。我們現在有了48位的結果,或者說8組6比特數據。我們現在要對每組的6比特執行一些奇怪的操作:

我們將它作為一張被稱為“S盒”的表格的地址。每組6比特都將給我們一個位於不同S盒中的地址。在哪個地址里存放着一個4比特的數字。這個4比特的數字將會替換掉原來的6個比特。最終結果就是,8組6比特的數據被轉換為8組4比特(一共32位)的數據。

將上一步的48位的結果寫成如下形式:

Kn+E(Rn-1)=B1B2B3B4B5B6B7B8

每個Bi都是一個6比特的分組,我們現在計算

S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8)

其中,Si(Bi)指的是第i個S盒的輸出。

為了計算每個S函數S1,S2,,,S8,取一個6位的區塊作為輸入,輸出一個4位的區塊。決定S1的表格如下:

S1Column Number

Row                                
No. 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7
1 0 15 7 4 14 2 13 1 10 6 12 11 9 5 3 8
2 4 1 14 8 13 6 2 11 15 12 9 7 3 10 5 0
3 15 12 8 2 4 9 1 7 5 11 3 14 10 0 6 13

如果S1是定義在這張表上的函數,B是一個6位的塊,那么計算S1(B)的方法是:B的第一位和最后一位組合起來,的二進制數決定一個介於0和3之間的十進制數(或者二進制00到11之間)。設這個數為i,B的中間4位二進制數代表一個介於0到15之間的二進制數(二進制0000到1111)。設這個數為j。查表找到第i行第j列的那個數,這個是一個介於0和15之間的數,並且它是能由一個唯一的4位區塊表示的。這個區塊就是函數S1輸入B得到的輸出S1(B)。比如,對輸入B=011011,第一位是0,最后一位是1,決定了行號是01,也就是十進制的1,中間4位是1101,也就是十進制的13,雖有列號是13.查表第一行第13列我們得到數字5.

這就決定了輸出;5的二進制是0101,所以輸出就是0101,即S1(011011)=0101。

同理,定義這8個函數S1,S2,,,S8:

S1
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

 

 

S2
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

 

S3
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

 

S4
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

 

S5
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

 

S6
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

 

S7
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

 

S8
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

例子:對弈第一輪,我們得到這8個S盒的輸出:

K1+E(R0)=011000 010001 011110 111010 100001 100110 010100 100111

S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8)=0101 1100 1000 0010 1011 0101 1001 0111

函數f的最后一步就是對S盒的輸出進行一個變換來產生最終值:

f=P(S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8))

變換P由如下表格定義。P輸入32位數據,通過下表產生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

比如對8個S盒的輸出:

S1(B1)S2(B2)S3(B3)S4(B4)S5(B5)S6(B6)S7(B7)S8(B8)=0101 1100 1000 0010 1011 0101 1001 0111

我們得到:

f=0010 0011 0100 1010 1010 1001 1011 1011

那么R1=L0+f(R0,K1)

= 1100 1100 0000 0000 1100 1100 1111 1111 
+ 0010 0011 0100 1010 1010 1001 1011 1011 
= 1110 1111 0100 1010 0110 0101 0100 0100

 在下一輪迭代中,我們的L2=R1,這就是我們剛剛計算的結果。之后,我們必須計算R2=L1+f(R1,K2),一直完成16個迭代之后,我們有了區塊L16和R16,。接着我們逆轉兩個區塊的順序得到一個64位的區塊:

R16L16

然后,我們對其執行一個最終的IP-1,其定義如下:

 
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  45  13  53  21  61  29 
36  44  12  52  20  60  28 
35  43  11  51  19  59  27 
34  42  10  50  18  58  26 
33  41  49  17  57  25 

也就是說,該變換的輸出的第一位是輸入的第40位,第二位是輸入的8位,一直到將輸入的第25位作為輸出的最后一位。

比如,我們使用上述方法得到了第16輪的左右兩個區塊:

L16 = 0100 0011 0100 0010 0011 0010 0011 0100 
R16 = 0000 1010 0100 1100 1101 1001 1001 0101

我們將兩個區塊調換位置,然后執行最終變換:

R16L16 = 00001010 01001100 11011001 10010101 01000011 01000010 00110010 00110100
IP-1 = 10000101 11101000 00010011 01010100 00001111 00001010 10110100 00000101

寫成16進制得到:

85E813540F0AB405

這就是明文M=0123456789ABCDEF的密文:85E813540F0AB405

解密就是加密的反過程,執行上述步驟,只不過在那16輪迭代中,調轉左右子秘鑰的位置而已。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM