2016-08-10 58 views
0

我正在評審一個應用程序,我們應該檢查加密算法和使用的密鑰的強度。從我對代碼的回顧中,我可以看出他們正在使用3DES算法,我從使用中提到的「DES/ECB/NoPadding」這一行中找到了算法。查找是否使用雙倍長度或三倍長度的3DES

不過在搜索加密後,我發現上面提到的加密只有56位的密鑰大小。參考鏈接如下:

但是,應用程序開發人員說是,他們使用雙長度3DES。有了上述數據,我們只能發現3DES已被使用,無法計算出密鑰大小。該應用程序是用JAVA開發的。

有人可以幫我找出雙倍長度或三倍長度3DES已被使用的方法嗎?

(OR)

提供雙倍長度或三倍長度的3DES實現細節?以便我們能夠弄清楚在我的情況下可以使用什麼。

+2

您如何期望在沒有大量加密知識背景的情況下查看加密代碼? – zaph

+1

這可能是過時的文檔,或者他們根本不知道他們在說什麼。無論如何,現在不應該使用DES和雙密鑰3DES,因爲它們只提供56位和80位的安全性。我建議使用AES,它具有比任何DES/3DES變體最小的密鑰尺寸更好的安全保證。 –

回答

1

如果他們使用的javax.crypto只有DES/ECB/NoPadding,那麼他們沒有使用3DES,他們使用DES。不僅如此,他們使用的是絕對不推薦的ECB。當然,他們可以用標準的DES來推出他們自己的「雙倍長度3DES」(不管這意味着什麼),但那是另一個警告信號。

P.S.如果你不得不在谷歌加密,爲什麼你甚至審查代碼?你不知道代碼是否安全,正如這個問題所證明的那樣。

+0

注意OP clams是「安全分析師」。 – zaph

+0

自由職業安全分析師,ouch。 – Kayaman

+0

我不是具有編碼背景的人,既不是編碼分析師,也不是安全分析師的安全問題。想從專家那裏獲得幫助,但似乎有些人只是爲了誇耀自己。我不希望你爲我審查它,只是指出正確的做法綽綽有餘。非常感謝。 – mjoi

0

首先,我不是密碼學方面的專家,所以請採取一些適中的答案。

什麼是double length 3DES?

三重DES加密涉及具有雙長(16字節)的密鑰K =(K 大號一個 8字節密文塊加密的8字節明文塊||ķř )如下:
Y = DES3(K)[X] = DES(K 大號)[DES -1(K ř)[DES(K 大號)[X]]]
解密發生如下:
X = DES -1(K 大號)[DES(K ř)[DES -1(K 大號)[Y]]]

EMV 4.2: Book 2 - Security and Key Management從兩者。


這裏是一個將如何在Java中實現這一點:

import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 

public class Test3DES { 
    public static void main(String[] args) throws Exception { 
     //byte length has to be mutiple of 8! 
     String plaintext = "Attack at dawn!!"; 
     byte[] plainBytes = plaintext.getBytes("UTF-8"); 
     byte[] encrypted = encrypt(plainBytes); 
     byte[] decrypted = decrypt(encrypted); 

     System.out.println("Original message: "); 
     System.out.printf("Text: %s%n", plaintext); 
     System.out.printf("Raw bytes: %s%n", toHexString(plainBytes)); 
     System.out.println("---"); 
     System.out.println("Encrypted message: "); 
     System.out.printf("Text: %s%n", new String(encrypted, "UTF-8")); 
     System.out.printf("Raw bytes: %s%n", toHexString(encrypted)); 
     System.out.println("---"); 
     System.out.println("Decrypted message: "); 
     System.out.printf("Text: %s%n", new String(decrypted, "UTF-8")); 
     System.out.printf("Raw bytes: %s%n", toHexString(decrypted)); 
    } 

    private static String toHexString(byte[] array) { 
     StringBuilder sb = new StringBuilder(); 
     for (byte b : array) { 
      sb.append(String.format("%02X ", b)); 
     } 
     return sb.toString(); 
    } 

    private static byte[] encrypt(byte[] message) throws Exception { 
     Cipher encr1, decr2, encr3; 
     SecretKeySpec kL, kR, tmp; 

     kL = new SecretKeySpec(new byte[] {0, 1, 2, 3, 4, 5, 6, 7}, "DES"); 
     kR = new SecretKeySpec(new byte[] {8, 9, 10, 11, 12, 13, 14, 15}, "DES"); 

     encr1 = Cipher.getInstance("DES/ECB/NoPadding"); 
     decr2 = Cipher.getInstance("DES/ECB/NoPadding"); 
     encr3 = Cipher.getInstance("DES/ECB/NoPadding"); 

     encr1.init(Cipher.ENCRYPT_MODE, kL); 
     decr2.init(Cipher.DECRYPT_MODE, kR); 
     encr3.init(Cipher.ENCRYPT_MODE, kL); 

     return encr3.doFinal(decr2.doFinal(encr1.doFinal(message))); 
    } 

    private static byte[] decrypt(byte[] message) throws Exception { 
     Cipher decr1, encr2, decr3; 
     SecretKeySpec kL, kR; 

     kL = new SecretKeySpec(
      new byte[] {0, 1, 2, 3, 4, 5, 6, 7}, 
      "DES" 
     ); 
     kR = new SecretKeySpec(
      new byte[] {8, 9, 10, 11, 12, 13, 14, 15}, 
      "DES" 
     ); 

     decr1 = Cipher.getInstance("DES/ECB/NoPadding"); 
     encr2 = Cipher.getInstance("DES/ECB/NoPadding"); 
     decr3 = Cipher.getInstance("DES/ECB/NoPadding"); 

     decr1.init(Cipher.DECRYPT_MODE, kL); 
     encr2.init(Cipher.ENCRYPT_MODE, kR); 
     decr3.init(Cipher.DECRYPT_MODE, kL); 

     return decr3.doFinal(encr2.doFinal(decr1.doFinal(message))); 
    } 
} 

輸出:

Original message: 
Text: Attack at dawn!! 
Raw bytes: 41 74 74 61 63 6B 20 61 74 20 64 61 77 6E 21 21 
--- 
Encrypted message: 
Text: #�Jɚe�P�ϸ5�%t� 
Raw bytes: 23 B4 4A C9 9A 65 C5 50 90 CF B8 35 9A 25 74 A2 
--- 
Decrypted message: 
Text: Attack at dawn!! 
Raw bytes: 41 74 74 61 63 6B 20 61 74 20 64 61 77 6E 21 21 

因此,要回答你的問題 - 你正在尋找代碼中16字節的密鑰大小。在我的代碼片段中,密鑰由kLkR組成,每個8字節,共16個。

+0

由於加密數據基本上是隨機字節,而不是可打印字符,所以通常將其顯示爲十六進制,因此'# ɚ ϸ ϸ is is is is is isis is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is#########使用三個DES實例進行加密和使用3DES也是一件奇怪的事情,許多3DES實現如果提供16字節密鑰,默認情況下會使用第一個8字節的第三個8字節。有趣的是,密鑰是一個不好的例子,因爲DES忽略每個字節的LSB,該位最初用於奇偶校驗,因此「{0,1,2,3,4,5,6,7}」和「{0,0 ,2,2,4,4,6,6}「基本上是相同的關鍵。 – zaph

+0

@ zaph我現在意識到可打印的字符表示是一個糟糕的選擇 - 如果我不這樣做,你非常歡迎編輯我的答案。所以你說我應該用鍵{'KL,KR,KL}'來使用3DES?這似乎是一個更好的主意!關於這些關鍵,我不認爲在這種情況下力量是重要的,但仍然......感謝你指出了這一點。 –

+0

@ zaph在問題中提到密碼是用** DES/ECB/NoPadding **算法實例化的。如果這個問題是有幫助的,我仍然認爲它應該保留這種形式,也許只是提到改進。 –