0

I'm trying to encrypt data using triple DES with two different keys, so given the two keys k1 and k2 the cryptotext would be Ek1(Dk2(Ek1(plaintext))) where E is Encryption and D Decryption. I'm trying to simulate this using DES algorithm from java. Here is the code:

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;
}

I have this error: javax.crypto.BadPaddingException: Given final block not properly padded when trying to decrypt at this line of code:

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

Can you help me to resolve this problem or do you know a direct method to encrypt data using triple DES with two different keys with total key length of 128 bits? I didn't find any algorithm so I tried to simulate it using simple DES.

Jones
  • 1,036
  • 5
  • 20
  • 37

3 Answers3

3

You are converting arbitrary bytes to Strings, which is corrupting them. work entirely with bytes. if you need to convert the encrypted data to a String, then use Base64 encoding.

jtahlborn
  • 52,909
  • 5
  • 76
  • 118
  • 2
    but don't use base64 as in the code currently. use bytes. use base64 only at the end. – andrew cooke Oct 27 '13 at 01:50
  • @andrewcooke I'm having the same problem, I don't wan't to use `DESede`, my project is to implement `TripleDES` using `DES`, so do you have any idea on how to fix this problem without using `DESede`? – Firas Al Mannaa Apr 05 '15 at 19:18
2

Why not just use the included DESede algorithm?

Change all your DES code instances to DESede and change your Key Generation method to as such:

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;
}

Note how the getInstance() method is now supplied with DESede and the key size has been increased to 112 (168 for three keys).

Change your Cipher instances from:

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

to

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

And you are set.

initramfs
  • 8,275
  • 2
  • 36
  • 58
0

Just wanted to point out that DES with a 112-bit key is, in fact, double DES not triple DES which has a 168-bit key (3*56). Double DES should never be used because of the meet-in-the-middle attack (MITM) https://en.wikipedia.org/wiki/Meet-in-the-middle_attack

In summary single DES (56-bits), double DES (112-bits) and triple DES (168-bits) shouldn't be used anymore as they don't provide 128 bits of security.

Daniel Gartmann
  • 11,678
  • 12
  • 45
  • 60