0

我正在尝试使用具有两个不同密钥的三重 DES 加密数据,因此给定两个密钥 k1 和 k2,密文将是 Ek1(Dk2(Ek1(plaintext))),其中 E 是加密和 D 解密。我正在尝试使用 java 中的 DES 算法来模拟这一点。这是代码:

public static void main(String[] args) {

    SecretKey k1 = generateDESkey();
    SecretKey k2 = generateDESkey();

    String firstEncryption = desEncryption("plaintext", k1);
    String decryption = desDecryption(firstEncryption, k2);
    String secondEncryption = desEncryption(decryption, k1);

}

public static SecretKey generateDESkey() {
    KeyGenerator keyGen = null;
    try {
        keyGen = KeyGenerator.getInstance("DES");
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    keyGen.init(56); // key length 56
    SecretKey secretKey = keyGen.generateKey();
    return secretKey;
}

public static String desEncryption(String strToEncrypt, SecretKey desKey) {
    try {
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        String encryptedString = Base64.encode(cipher.doFinal(strToEncrypt.getBytes()));
        return encryptedString;


    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

public static String desDecryption(String strToDecrypt, SecretKey desKey) {
    try {
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        String decryptedString = new String(cipher.doFinal(Base64.decode(strToDecrypt)));
        return decryptedString;


    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (NoSuchPaddingException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (InvalidKeyException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalBlockSizeException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (BadPaddingException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    } catch (Base64DecodingException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

我有这个错误:javax.crypto.BadPaddingException:在这行代码尝试解密时,给定最终块未正确填充:

String decryptedString = new String(cipher.doFinal(Base64.decode(strToDecrypt)));

您能帮我解决这个问题吗,或者您知道使用三重 DES 和两个不同密钥(总密钥长度为 128 位)加密数据的直接方法吗?我没有找到任何算法,所以我尝试使用简单的 DES 来模拟它。

4

3 回答 3

3

您正在将任意字节转换为字符串,这会破坏它们。完全使用字节。如果您需要将加密数据转换为字符串,则使用 Base64 编码。

于 2013-10-26T18:40:42.913 回答
2

为什么不直接使用包含的 DESede 算法呢?

将您的所有 DES 代码实例更改为 DESede 并将您的密钥生成方法更改为:

public static SecretKey generateDESkey() {
    KeyGenerator keyGen = null;
    try {
        keyGen = KeyGenerator.getInstance("DESede");
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }
    keyGen.init(112); // key length 112 for two keys, 168 for three keys
    SecretKey secretKey = keyGen.generateKey();
    return secretKey;
}

请注意,现在 DESede 提供了 getInstance() 方法,并且密钥大小已增加到 112(三个密钥为 168)。

从以下位置更改您的密码实例:

Cipher.getInstance("DES/ECB/PKCS5Padding");

Cipher.getInstance("DESede/ECB/PKCS5Padding");

你已经准备好了。

于 2013-10-26T18:42:07.767 回答
0

只是想指出,具有 112 位密钥的 DES 实际上是双 DES,而不是具有 168 位密钥 (3*56) 的三重 DES。由于中间相遇攻击 (MITM) https://en.wikipedia.org/wiki/Meet-in-the-middle_attack,永远不应使用双 DES

总之,单 DES(56 位)、双 DES(112 位)和三重 DES(168 位)不应再使用,因为它们不提供 128 位的安全性。

于 2020-07-27T12:21:59.897 回答