DES算法詳解與源碼


網上關於DES算法的講述有很多,大致思路一致。但是很多細節的處理上沒有交代清楚,源碼質量也參差不齊,為此也花了很多時間研究了一下,現在把完整思路和源碼整理如下。

 

1. DES算法簡介:

  

DES算法為密碼體制中的對稱密碼體制,又被稱為美國數據加密標准,是1972年美國IBM公司研制的對稱密碼體制加密算法。 明文按64位進行分組,密鑰長64位,密鑰事實上是56位參與DES運算(第8、16、24、32、40、48、56、64位是校驗位, 使得每個密鑰都有奇數個1)分組后的明文組和56位的密鑰按位替代或交換的方法形成密文組的加密方法。

 

2. DES步驟:

  1.首先輸入一個8字節的密鑰M8。將8字節的密鑰轉換成成64位的二進制位M64。其中第8,16,24,32,40,48,56,64位是校驗位, 使得每個密鑰都有奇數個1。所以密鑰事實上是56位,儲存時可以先儲存64位,在下一步驟中的PC1置換中可以扣除。

    這里注意高低位問題:比如'L'的ASCII為75,轉換為二進制為'01001011',在這里二進制從左到右為從高到低位,在密鑰轉換時,則從低位向高位儲存

    如:'L'的ASCII為75,二進制為'01001011',轉換至數組內為:char a = {0,1,0,0,1,0,1,1};

    網上各源代碼對此處的處理有所不同,這種處理辦法能夠獲得正確的解析結果。

  2. 將64位M64經過PC1置換轉換為56位(扣除奇偶校驗位)。

    對這56位密鑰進行如下表的換位。

    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位移到第1位,第49位移到第2位,...... 以此類推。

  3. 變換后得到56位數據M56,將它分成兩部分,C[0][28], D[0][28]。

  4. 計算16個子密鑰。計算方法C[i][28] D[i][28]為對前一個C[i-1][28], D[i-1][28]做循環左移操作。16次的左移位數如下表:

      1,  1,  2,  2,  2,  2,  2,  2,  1,   2,  2,   2,   2,   2,   2,  1    (左移位數)

    在這里的16次循環中,每一次循環中,左移后,將C[i][28],D[i][28]重新湊成56位后,對這56位進行一次PC2置換,得到48位的子密鑰sub[i][48]。16次循環后就有16個子密鑰。PC2變換如下:

    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,

    表的意思是第14位移到第1位,第17位移到第2位,以此類推。在此過程中,發現第9,18,22,25, 35,38,43,54位丟棄。

*********************************************************************

  5.得到子密鑰以后,就是對明文進行加密和解密操作了,加密和解密操作具有對稱性,因此介紹加密操作:

  6.輸入明文,要求達到8字節,若沒有達到8字節則進行擴展,擴展至8字節(補0或補'\0')。

  7.將8字節的明文轉換成成64位的二進制位。

  8. 對64bit的明文輸入進行換位變換。換位表如下:

    58, 50, 12, 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位移到第1位,第50位移到第2位,...... 依此類推。得到64位數據data[64]。

  9.接下來將進入循環處理階段,總共進行16次循環,每次循環遵循如下操作:

  for(int i=0;i<16;i++)

  {

    10.將64位數據data[64]前后分成兩塊L[i][32], R[i][32]。

    11.對R[i][32]進行擴展變換成48位數,方法如下, 記為E(R[i][32])

      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,

    12.將E(R[i][32])與sub[i][48](由密鑰處理獲得的子密鑰,見步驟4)作異或運算,得到48位數B[48]。

    13.將48位數順序分成8份,6位一份,B[48]->B[8][6]。

    14.使用8個S盒對分成8份的B[8][6]進行替換,步驟如下:

        a) 取出B[j][6]的第1位和第6位連成一個2位二進制數m,范圍(0-3),轉換成十進制數后作為第j個S盒的行標

          如:假設B[0]為'010011',則取出第一位0和第六位1,組成01,01轉換為十進制為1,因此m代表了第0個S盒中的第2行(數組下標從0開始)

        b) 取出B[j][6]的第2、3、4、5位連成一個4位二進制數n,范圍(0-15),轉換成十進制數后作為第j個S盒的列標

          如:假設B[0]為'010011',則取出'1001',轉換成十進制為9,因此n代表了第0個S盒中的第10列(數組下標從0開始)

        c) 有了行標和列表則進入第j個S盒中查找對應的數字

          接上例,第0個S盒中第二行第十列獲得數字:6

        d) 將獲得的數字轉換成二進制,替換48位的B中的前4位。

          接上例,6轉換為二進制為0110,這樣B的前四位就為0110,循環后從第5位繼續。

        e) 經過8次循環,每次替換4位,最終B的前32位則為我們新獲得的加密數據B[32]

    15.對B[32]進行如下變換得到B'[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,

    16.B'[32]與L[i][32]作異或運算,把結果覆蓋data[64]的左半部分,若i!=15,則交換data[64]的左右部分(即異或運算結果作為下一次循環的右邊,原來的右邊作為下      一次運算結果的左邊)。若i=15,則不進行交換。

  }

  17. 結束循環后,將16次處理過后的data[64]進行一次逆初始置換,這是對第8步的逆變換

     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

  這樣就得到了最終的密文了QUQ~

 

  解密過程同加密過程完全相同,不同的是對子密鑰的異或順序不同,加密過程 i 從0-15與子密鑰配對,解密過程中則從15-0與子密鑰進行異或。

  

源代碼見鏈接:

http://pan.baidu.com/s/1c0D1RAo

 

5.1.cpp為字符char與8位二進制char之間的轉換

 

5.2&5.3.cpp為DES的加密程序,其中輸出中間過程如下:

a. 密鑰對應密鑰的64位比特(8X8形式輸出,使用5.1中的函數進行轉換);

b. 經過置換選擇1后,分別輸出的C0(28位)和D0(28位)對應的比特;

c. 輸出第5次迭代時,產生的子密鑰K5所對應的48位比特;

d. 原文對應的64位2進制比特序列;

e. 64比特序列經過初始置換IP后,得到新的64位比特;

f. 乘積變換需要進行16次迭代,輸出經過5次迭代后,得到的64位比特;

g. 輸出完成乘積變換(16次迭代)后得到的64位比特;

h. 輸出加密后的密文的64位比特;

 

5.4.cpp是針對一段指定的密文進行解密的程序。

 

5.5.cpp,將給定的文本文件“DES.txt”進行加密,密鑰依舊是“KEYMIYAO”,把密文保存在另一個文本文件(“DES_Encrypt.txt”)中,然后對這個文件進行解密,得到的原文保存到文本文件(“DES_Final.txt”)中。其中包括了字符不足時的擴展。將此文件加入vs中后要自己創建以上提到的3個txt資源文件。

 

添加txt文本的方法如下:

  VC++6.0中,點擊菜單欄 文件 - 新建

    在彈出的對話框中選擇文本文件,然后鍵入指定的文件名。然后將其拖入Resource File文件夾。

    

    

    也可以右鍵Resource File文件夾,直接添加。

  VS2012中可以直接右鍵Resource File文件夾。新建項-添加,在實用工具內選擇txt文件即可。

 

 

DESc版本.cpp,是DES的c語言實現,效率高,寫的好。別看我我是從信息安全專業那里扒來的捂臉QUQ。

 

在低版本的VS中可能會出現for循環中不允許聲明int的問題,自行修改int變量提至函數開頭。

有空再來補充3DES算法了··

 


免責聲明!

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



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