查找是使用了双倍长度还是三倍长度的3DES

时间:2016-08-10 16:24:12

标签: java encryption cryptography 3des tripledes

我正在审核一个应用程序,我们应该检查加密算法和使用的密钥的强度。从我对代码的回顾来看,我能弄清楚的是他们正在使用3DES算法,我从提到的线路中找到了" DES / ECB / NoPadding "正在使用。

然而,在搜索加密后,我发现上面提到的加密只有56位的密钥大小。参考链接如下:

但是,应用程序开发人员说他们使用Double length 3DES。有了上述数据,我们只能弄清楚3DES已被使用,无法弄清楚密钥大小。该应用程序是在JAVA开发的。

有人可以帮助我找出使用双倍长度或三倍长度3DES的方法吗?

(OR)

提供双倍长度或三倍长度的3DES实施细节?这样我们就可以弄清楚在我的情况下可以使用什么。

2 个答案:

答案 0 :(得分:1)

如果他们只使用DES/ECB/NoPadding的javax.crypto,那么他们没有使用3DES,他们正在使用DES。不仅如此,他们使用的是ECB,绝对不推荐。当然,他们可以使用标准DES推出他们自己的“双倍长度3DES”(无论这意味着什么),但这是另一个警示标志。

P.S。如果您不得不谷歌加密,为什么还要查看代码?你不知道代码是否安全,正如这个问题所证明的那样。

答案 1 :(得分:0)

首先,我不是密码学方面的专家,所以请适当地回答这个问题。

什么是双倍长3DES?

  

三重DES加密涉及对一个8字节的明文块进行加密   具有双倍长度(16字节)密钥K =(K L || K R )的8字节密文块如下:
  Y = DES3(K)[X] = DES(K L )[DES -1 (K R )[DES(K L )[X]]]
  解密发生如下:
  X = DES -1 (K L )[DES(K R )[DES -1 (K < sub> L )[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个。