密碼學——DES加密算法
DES 算法是一種常見的分組加密算法,由IBM公司在1971年提出。DES 算法是分組加密算法的典型代表,同時也是應用最為廣泛的對稱加密算法。本文將詳細講述DES 的原理以及實現過程。
概念
對稱加密
通信雙方同時掌握一個密鑰,加密解密都是由一個密鑰完成的(即加密密鑰等於解密密鑰,加解密密鑰可以相互推倒出來)。雙方通信前共同擬定一個密鑰,不對第三方公開。
分組密碼
如果經過加密所得到的密文僅與給定的密碼算法和密鑰有關,與被處理的明文數據在整個明文中的位置無關,則稱為分組密碼體制。通常以大於等於64位的數據塊為單位,加密得相同長度的密文。DES 加密算法中,明文和密文為 64 位分組。密鑰的長度為 64 位,但是密鑰的每個第八位設置為奇偶校驗位,因此密鑰的實際長度為56位。
DES加密流程
DES 加密算法大致分為 4 個步驟:
(1)初始置換
(2)生成子密鑰
(3)迭代過程
(4)逆置換

下面詳細介紹每一部分的算法,文中提到的各種置換規則表(IP, PC_1, PC_2, ...)都是經DES算法規定、公開的算法參數。具體內容可參考這里。文中提到的置換操作,簡單實現如下
def permutation(src, rule):
# src:置換源向量
# rule:置換規則向量, rule[i]的值val表示將src[val]移到輸出的第i位
res = []
for i in rule:
res.append(src[i-1])
return res
-
初始置換
- 首先將明文\(M[64]\)使用初始置換IP(initial permutation)表進行置換得到\(M'[64]\)
- 將\(M'[64]\)按前32位,后32位分為兩部分\(L_0[32],\ R_0[32]\)
-
生成子密鑰
在后續的迭代過程中,每一輪需要用到不同的子密鑰參與計算,使用密鑰\(K\)生成子密鑰的過程如下:
- 使用置換表PC_1將密鑰\(K[64]\)縮減為56位的數據\(K'[56]\)
- 進行16輪迭代生成16個子密鑰,對於第\(i\)次迭代:
- 取\(K'\)的前28位作為\(Ci\), 后28位作為\(Di\)
- 查找移動位數表shift表中規定的第\(i\)輪對\(C_i\)和\(D_i\)進行左移的位數\(j\)
- 將\(C_i\)和\(D_i\)進行循環左移\(j\)位
- 將移位后的\(C_i\)和\(D_i\)合並得到\(K'_i\),使用PC_2置換表對\(K'_i\)進行置換,得到本次迭代生成的密鑰\(K_i\)
-
迭代過程
將初始置換得到的\(L_0\)和\(R_0\)作為輸入,設\(L_i[32]\)和\(R_i[32]\)為第i次迭代結果的左半部分與右半部分,子密鑰\(K_i\)為第\(i\)輪的48位加密密鑰。定義運算規則:
\[\begin{split} & L_i = R_{i-1} \\ &R_i = L_{i-1} \oplus f(R_{i-1}, K_i) \end{split} \]整個迭代過程如下:

將上面的迭代過程執行16次。每一輪迭代的具體過程如下:
首先,令上一輪的輸出為\(L_{i-1}[32],\ R_{i-1}[32]\),則在第\(i\)次迭代中,首先令\(L_i = R_{i-1}\)。將\(R_{i-1}\)作為輸入,進行如下的計算:
-
擴展置換E:\(R_{i-1}\)在與\(K_i\)進行異或之前,需要通過E置換表將位數擴展到48位,令異或后的結果為\(res'[48]\)。
-
S盒替換:將\(res'[48]\)通過S盒替換,將位數變換回32位。具體過程為:
- 將\(res'\)按每6位進行分組,得到8組分片\(F\)
- 對於每個分片\(F_i[6]\),組合第1,6位的二進制值,計算對應的十進制值row,組合第2到第5位的二進制值,計算對應的十進制值col。對於分片\(i\),使用規則表\(S_i[64]\)進行轉換,查找\(S_i[row*16+col]\)的值,轉換為4位的二進制值。如果位數不足,在左側用0填充。
- 將每個6位的分片通過\(S_i\)轉換后得到的4位輸出按序合並,得到最后32位的輸出res''。
-
P盒置換:使用置換表P對\(res''\)進行置換,得到函數\(f\)的最終結果res''。
-
最后使用\(res''\)與上一輪的\(L_{i-1}[32]\)進行異或,得到新的\(R_i[32]\)。
-
-
逆置換
將上述16次迭代得到的\(L_{16},\ R_{16}\)合並,將得到的結果使用逆置換表R進行轉換,得到最后的密文輸出。
