How to Use 3DES Encryption and Decryption in Java

Modern applications often require a secure way to handle sensitive data. One popular encryption algorithm you might encounter is 3DES (Triple Data Encryption Standard). If you’re attempting to encrypt and decrypt strings using 3DES in Java, you may run into issues, as illustrated by a common problem among developers: the inability to decrypt a message back to its original form. This post will help you understand how to use 3DES encryption and decryption correctly in Java.

The Problem

Imagine you’ve written some code to encrypt a string—let’s say, the string “kyle boon.” After running your encryption method, you try to decode the result but fail to get back the original string. Many developers face a similar challenge, often due to handling byte arrays improperly or missing critical steps in their code.

One developer shared, “Every method I write to encode a string in Java using 3DES can’t be decrypted back to the original string.” This common mistake usually stems from misunderstanding how byte arrays and string representations work in Java.

The Solution

Let’s take a look at a simplified, corrected implementation of 3DES encryption and decryption in Java. This code allows you to encrypt a text input and then easily decrypt it back to the original text.

Step-by-Step Code Explanation

  1. Imports:

    import java.security.MessageDigest;
    import java.util.Arrays;
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
  2. Class Definition:

    public class TripleDESTest {
    
  3. Main Method: In your main method, you will first define the text to be encrypted.

    public static void main(String[] args) throws Exception {
        String text = "kyle boon";
        byte[] codedtext = new TripleDESTest().encrypt(text);
        String decodedtext = new TripleDESTest().decrypt(codedtext);
    
        System.out.println(codedtext);
        System.out.println(decodedtext); // "kyle boon"
    }
    
  4. Encrypt Method: This method encodes the input message using the 3DES algorithm:

    public byte[] encrypt(String message) throws Exception {
        final MessageDigest md = MessageDigest.getInstance("md5");
        final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8"));
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }
    
        final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        final byte[] plainTextBytes = message.getBytes("utf-8");
        return cipher.doFinal(plainTextBytes);
    }
    
  5. Decrypt Method: This method reverses the encryption process:

    public String decrypt(byte[] message) throws Exception {
        final MessageDigest md = MessageDigest.getInstance("md5");
        final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8"));
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    
        for (int j = 0, k = 16; j < 8;) {
            keyBytes[k++] = keyBytes[j++];
        }
    
        final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        decipher.init(Cipher.DECRYPT_MODE, key, iv);
        final byte[] plainText = decipher.doFinal(message);
    
        return new String(plainText, "UTF-8"); // Convert byte array to string
    }
    

Key Takeaways

  • Correctly Handle Byte Arrays: When decoding, ensure you convert the byte array back into a string using new String(plainText, "UTF-8") instead of calling toString() on it. This avoids getting garbage output.

  • Base64 Encoding: If you plan to transmit the encrypted byte array over a text medium, consider using Base64 encoding. Ensure to decode it properly during decryption.

  • Exception Handling: The code contains exception handling to manage various encryption errors, making it robust.

Now you have a clear and effective approach to using 3DES encryption and decryption in your Java applications. By following the above explanation and code snippets, you can implement this powerful encryption method successfully.