2016-08-10 37 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 **算法实例化的。如果这个问题是有帮助的,我仍然认为它应该保留这种形式,也许只是提到改进。 –