我們的任務分為4個部分:
1.了解DES加密算法整體流程。
2.了解DES加密算法細節。
3.使用python簡單實現DES算法加密主要過程
任務描述:DES加密算法實現流程解析。
1. DES算法的流程圖如下:
通過上面的流程圖,相信大家就可以大致了解了DES加密算法的流程。
我們可以轉化為文字:一開始輸入64位的明文數據;然后進行初始置換(IP);初始置換之后,將生成的64位數據分為左右兩部分,每部分為32位,命名為L0、R0;然后這兩部分在密鑰的控制下,進行16輪完全相同的運算,我們稱為16輪迭代運算,每運算一次,左右兩部分的命名就改變一次,直到運算完成,L0變為L16,R0變為R16;在16輪運算完成之后,將L16和R16交換,並且合並為64位;再經過末置換(初始置換的逆置換/終止置換),輸出密文。
應該注意的是,我們上面說到的16輪完全相同的運算,指的是運算所使用的函數或者說算法是一樣的,但是參數L、R以及K是不相同的,L、R不用多說,就是上次運算所得的L和R,但每一輪參與運算的K是我們的入口參數Key,經過某個特定的交換規則交換后,生成16個子秘鑰,我們命名為K1,K2,K3….K16。
具體的交換規則以及過程我們會在后面的任務中進行詳細解釋。
2. 函數f
上面我們提到,經過初始置換后,會進行16輪相同的運算,現在我們簡單介紹一下這個運算函數中,都進行了哪些運算,運算的主要流程圖如下:
從上圖我們可以知道,函數f主要對數據的右半部分R進行了操作,
a. 先對其進行擴展置換,使其變為48位的數據,
b. 然后生成的數據再與子密鑰進行異或運算,
c. 再以異或運算后的48位數據進行S盒代替,將48位的數據,轉換為32位的數據,
d. 再進行P盒置換,生成32位的數據
e. 最后將P盒置換生成的數據與本輪運算的L進行異或,生成新的R。
f. 而新的L是直接由本輪的R進行替換
任務描述:DES加密過程詳解。
1. IP置換(初始置換)
初始置換的原理其實很簡單,根據一個初始置換表,對照表中的數值,將明文數據相應位置的數據移動到該數據所在的位置即可,初始置換表如下:
從上表我們可以總結出,初始置換表的規律其實就是(其實不用太在意這個規律):
a. 偶數與奇數分開(1~64),然后分為上下兩部分,分布在置換表中,偶數在上,奇數在下。
b. 在偶數與奇數內部,又遵從“從右到左,從上到下,從小到大”的排列。
為了更直觀的展示初始置換,我們不使用實際加密中的二進制數據,我們假設現在要加密的這些就是二進制數據,如下:
我們這樣理解,a就是加密的64位數據中的第一位,b就是第二位,依次類推,那么,初始置換的過程就應該是這樣的:
先置換a:
然后置換b:
直到置換完:
至此我們便得到了初始置換之后的數據
Data=“5XPHzrjb7ZRJBtld91TLDvnf=3VNFxph4WOGyqia6YQI(i)Askc80SKCume+2UMEwog”
L0 = “5XPHzrjb7ZRJBtld91TLDvnf=3VNFxph”
R0 = “4WOGyqia6YQI(i)Askc80SKCume+2UMEwog”
2. 函數f
初始置換之后,就是我們的16輪運算,我們需要知道的是運算函數f, 在運算過程中數據與密鑰結合。f函數作用於每輪的K(子密鑰)值和每輪的待加密文本的右半部分(R)。//我們后面出現的K0、R0等等,字母后面有數字的,都是代表對應輪數運算中的K、R等。
從我們實驗任務一中的函數f流程圖,我們可以清晰的了解到,經過一輪運算之后,左半部分變為原來的右半部分,可理解為:L1=R0,新的右半部分(R)是原來的左半部分與經過f函數處理的原右半部分進行異或運算后得到的(R1=L0^f(R0,K1))。
那么我們現在需要了解的就是這么幾個問題:
a. 子秘鑰K(1~16)是如何得到的?
b. 擴展置換的流程是如何的,其后的異或運算又是怎樣的?
c. S盒替換是如何替換的?
d. P盒置換又是如何操作的?
我們一次解決這幾個問題
1)問題a. 子秘鑰K
子秘鑰K的生成過程中,又有兩次置換,稱為壓縮置換1和壓縮置換2,大致流程圖如下:
從流程圖我們可以清楚的知道,初始密鑰在經過第一次壓縮置換之后,生成56位數據,再將這56位數據從中間拆分開來,命名為C0,D0,然后根據正在運算的輪數,將數據左移相應的位數,來得到C1和D1,最后將C1,D1合並為56位的數據,經過壓縮置換2之后,生成子密鑰K1,即生成了第一輪運算時使用的子密鑰。接下來的每一輪運算中的子密鑰K都是由上一輪生成的子密鑰經過這兩次壓縮置換得到的。不同的地方在於C和D循環左移的位數,在每一輪中都是不同的。具體的對應表如下(即C1、D1是由C0、D0移位得到,C2、D2是由C1、D1移位得到……..以此類推):
那么好,了解主要流程之后,我們再舉例子,為了直觀一點,我們還是使用“abc…..”來代替二進制的“0101”:
假設我們現在的初始秘鑰是8個字節,也就是64位:
“abcdefgh ijklmnop qrstuvwx yzABCDEF GHIJKLMN OPQRSTUV WXYZ0123 456789+=”
我們使用紅色字體標注的字母,就是我們前面預備知識提到的奇偶校驗位,這些位是密鑰的每個字節的最后一位,雖然也屬於密鑰,但是不參與加密運算,也就是去掉這些標注的紅色位,剩下的56位就是需要參與到壓縮置換1的數據,如下圖:
跟之前的置換一樣,將字母換到對應的位置上就可以了(為了方便我們在初始秘鑰的表格后面標注了每行最后一個參與置換的字母的位置,比如g是第7位,o是第15位):
那么經過這次置換呢,我們可以總結出壓縮置換1的規律:
就是將56位的數據從中間豎着分開,然后按照我們上圖(有點丑,不要在意這些細節)所示的順序排列。
經過壓縮置換1之后呢,我們就得到一個K0,再將這個K0拆分,得到C0、D0,進而得到C1、D1,最后得到K1。
壓縮置換1接下來的是拆分:
K0=“4WOGyqia5XPHzrjb6YQI(i)Askc7ZRJ+2UMEwog91TLDvnf80SKCumeBtld”
C0=“4WOGyqia5XPHzrjb6YQI(i)Askc7ZRJ”
D0=“+2UMEwog91TLDvnf80SKCumeBtld”
拆分之后我們得到C0、D0,再然后就是循環左移,求出C1、D1:
我們根據“輪數與左移位數”的對應表,得知,我們現在要求的是C1、D1,也就是第一輪運算,那么循環左移的位數就是1位,就可以得到:
C1=“WOGyqia5XPHzrjb6YQI(i)Askc7ZRJ4”
D1=“2UMEwog91TLDvnf80SKCumeBtld+”
如上,左移的同時還要保持位數不變,所以移動的數據又補充到后面。
C1D1= “WOGyqia5XPHzrjb6YQI(i)Askc7ZRJ42UMEwog91TLDvnf80SKCumeBtld+”
放在表格中(黑色表格中的是每一行最后一位的位數):
最后要得到子秘鑰K1,還需要進行壓縮置換2,經過壓縮置換2之后56位的C1D1被壓縮成48位的K1:
壓縮置換遵循的規則表如下:
得到K1:
K1=“jYH7WqG4bisPcI(i)zyR56aJArOvBM1KdUDe0wC8uL+otSnm92E”
至此我們便得到了第一輪的子密鑰:K1
2)問題b. 擴展置換E
接下來我們了解擴展置換E的細節:
擴展置換的作用對象是我們在初始置換后,將數據拆分為兩部分(L,R)中的右半部分R。
擴展置換表如下:
可能不太好理解,我們用文字描述一下,就是將數據R(32位),按照每4位一組,拆分成8個組,如圖,左右黑色的兩列是擴展時添加的數據,中間的就是分組后的數據R,表中的數字代表數據R中的位置。分成8組織后,遵循這樣的一個規則:每一組的頭部添加本組數據上一組的尾部,每一組的尾部添加本組數據下一組的頭部。即第一組數據,前面添加的是最后一組的最后一位數據,后面添加的是第二組的第一位數據…以此類推,如果還不懂,那么我再插一個圖:
好了,現在拿我們上面得到的R0進行擴展置換:
先分組:
R0=“4WOGyqia6YQI(i)Askc80SKCume+2UMEwog”
然后進行擴展:
之后我們便得到了擴展到48位的R0:
R0=“g4WOGYGYqia6a6YQI(i)AI(i)Askc8c80SKCKCume+e+2UMEMEwog4”
擴展置換E結束之后,我們要進行的就是K1與R0的異或運算,由於我們這里不是采用的真正的二進制數據,所以我們不做此步驟的詳細解釋,畢竟只是一個異或運算,很簡單。
3)問題c. S盒代替
S盒代替的作用,就是將我們上一步,R0與K1異或后得到的48位數據壓縮為32位數據。
S盒一共有8個,每一個都是一個4行16列的數組,具體如下:
接下來我們講解一下S盒代替的過程:
我們前面擴展置換后得到的R0是48位的數據,我們的S盒有8個,那么我們就需要將得到的R0平均分為8組,每組對應一個S盒。
每一組的數據長度為6位,假設第一組的二進制數據為:“100110”
那么,我們取第一位與最后一位,組成行數:“10”=2
取中間四位,組成列數:“0011”=3
那么,在對應的S1盒中,取2行3列的數據(第3行第4列):8
轉換為2進制:“1000”
那么就將這個得到的4位二進制數據,代替原來第一組的6位數據,這樣一來,等8個S盒全部代替完畢,我們就得到32位的數據。
4)問題d. P盒置換
S盒置換完成之后,要進行的就是P盒置換了,輸入32位的數據,得到32位的輸出。置換表以及置換舉例如下:
至此我們便得到了f(R0,K1),只要再與L0進行異或運算,就得到了第一輪運算最終的R1,然后再將R0的值賦給L1,就完成了第一輪的運算,得到了L1,R1。
3. 末置換(也稱初始置換的逆置換/終止置換)
經過16次的運算,我們在函數f的最后,會得到“L16、R16”,這正是我們需要的,然后將L16與R16合並,但是與之前的步驟中的合並不同,此次合並需要先交換二者的位置,也就是應該是R16L16。
合並之后我們就得到了長度為64位的數據,在用這64位數據進行末置換,最終得到的數據就是加密后的數據。
終止置換表如下(我們不再舉例,反正都一樣):
任務描述:使用python實現DES加密算法主要過程。
正如我們任務描述中所說的,我們只是用python實現以下簡單的加密步驟,我們在此次試驗中不考慮的情況有這些:
a. 需要加密的文本超過64位或者不足64位怎么辦?
b. 加密后的文本如何顯示(這涉及到編碼問題)
c. 用戶輸入的秘鑰超出8位長度或者不足8位長度怎么辦?
d. 得到一串密文應該如何解密(這也涉及到編碼的問題)
也就是我們這次的實驗任務,是利用python,將加密的細節展示出來,並與實驗環境中的cap4加密的結果進行比對,驗證我們的算法是否正確:
1. 我們首先要把加密過程中需要用到的置換表都准備好:
2. 我們知道,無論是要加密的文本,還是密鑰,在加密的過程中都是以二進制的形式被處理的,所以我們需要一個函數來對所有輸入的字符串進行處理,將其轉換為二進制,我們直接使用ord函數將輸入的數據轉換為其對應的unicode編碼的十進制,在轉換為二進制,因為python的bin函數轉換成的二進制會自動刪除高位的0,所以我們使用“{:08b}.format()”這樣的方式來使生成的二進制保持一定的位數:
3. 我們先將子密鑰的生成搞出來,如下圖,我們創建子秘鑰生成的函數,所需參數為初始密鑰的二進制文本,根據前面的原理知識,進行壓縮置換之后,分為C、D兩部分,然后進行移位,一口氣完成16次的移位之后,將生成的子密鑰全部保存在全局列表KS中,方便之后的加密函數調用這些子密鑰:
4. 加密函數,就不在這里細說了,看代碼中的注釋就可以理解了呢。
5. 我們進行測試:
6. 使用環境中的CAP4進行加密,比較生成的二進制: