How to use 3DES encryption / decryption in Java?

Every method I write to encode a string in Java using 3DES cannot be decrypted back to the original string. Does anyone have a simple piece of code that can simply encode and then decode a string back to the original string?

I know that I am making a very stupid mistake somewhere in this code. Here is what I have worked so far:

** Note that I am not returning the BASE64 text from the encryption method, and I am not encoding the base64 code in the decryption method because I was trying to find out if I was mistaken in the BASE64 part of the puzzle.

public class TripleDESTest { public static void main(String[] args) { String text = "kyle boon"; byte[] codedtext = new TripleDESTest().encrypt(text); String decodedtext = new TripleDESTest().decrypt(codedtext); System.out.println(codedtext); System.out.println(decodedtext); } public byte[] encrypt(String message) { try { 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"); final byte[] cipherText = cipher.doFinal(plainTextBytes); final String encodedCipherText = new sun.misc.BASE64Encoder().encode(cipherText); return cipherText; } catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); } catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); } catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); } catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); } catch (BadPaddingException e) { System.out.println("Invalid Key");} catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");} catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");} return null; } public String decrypt(byte[] message) { try { 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[] encData = new sun.misc.BASE64Decoder().decodeBuffer(message); final byte[] plainText = decipher.doFinal(message); return plainText.toString(); } catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); } catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); } catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); } catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); } catch (BadPaddingException e) { System.out.println("Invalid Key");} catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");} catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } 
+59
java encryption 3des
Aug 21 '08 at 15:25
source share
5 answers

Your code was fine, except for the Base 64 encoding bit (which you mentioned as a test), the reason the result may not make sense is because you are showing an array of raw bytes (doing toString () in an array of bytes returns an internal Java reference, not a string representation of the content ). Here is the version that has just been minced and that prints "kyle boon" as a decrypted string:

 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; public class TripleDESTest { 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); // this is a byte array, you'll just see a reference to an array System.out.println(decodedtext); // This correctly shows "kyle boon" } 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"); final byte[] cipherText = cipher.doFinal(plainTextBytes); // final String encodedCipherText = new sun.misc.BASE64Encoder() // .encode(cipherText); return cipherText; } 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[] encData = new // sun.misc.BASE64Decoder().decodeBuffer(message); final byte[] plainText = decipher.doFinal(message); return new String(plainText, "UTF-8"); } } 
+57
Aug 21 '08 at 17:59
source share

Here is a solution using the javax.crypto library and the apache commons codec library for encoding and decoding in Base64:

 import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import org.apache.commons.codec.binary.Base64; public class TrippleDes { private static final String UNICODE_FORMAT = "UTF8"; public static final String DESEDE_ENCRYPTION_SCHEME = "DESede"; private KeySpec ks; private SecretKeyFactory skf; private Cipher cipher; byte[] arrayBytes; private String myEncryptionKey; private String myEncryptionScheme; SecretKey key; public TrippleDes() throws Exception { myEncryptionKey = "ThisIsSpartaThisIsSparta"; myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME; arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT); ks = new DESedeKeySpec(arrayBytes); skf = SecretKeyFactory.getInstance(myEncryptionScheme); cipher = Cipher.getInstance(myEncryptionScheme); key = skf.generateSecret(ks); } public String encrypt(String unencryptedString) { String encryptedString = null; try { cipher.init(Cipher.ENCRYPT_MODE, key); byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT); byte[] encryptedText = cipher.doFinal(plainText); encryptedString = new String(Base64.encodeBase64(encryptedText)); } catch (Exception e) { e.printStackTrace(); } return encryptedString; } public String decrypt(String encryptedString) { String decryptedText=null; try { cipher.init(Cipher.DECRYPT_MODE, key); byte[] encryptedText = Base64.decodeBase64(encryptedString); byte[] plainText = cipher.doFinal(encryptedText); decryptedText= new String(plainText); } catch (Exception e) { e.printStackTrace(); } return decryptedText; } public static void main(String args []) throws Exception { TrippleDes td= new TrippleDes(); String target="imparator"; String encrypted=td.encrypt(target); String decrypted=td.decrypt(encrypted); System.out.println("String To Encrypt: "+ target); System.out.println("Encrypted String:" + encrypted); System.out.println("Decrypted String:" + decrypted); } } 

Execution of the above program leads to the following conclusion:

 String To Encrypt: imparator Encrypted String:FdBNaYWfjpWN9eYghMpbRA== Decrypted String:imparator 
+15
Nov 28 '12 at 19:29
source share

It was hard for me to figure this out, and this post helped me find the right answer for my case. When working with financial messages like ISO-8583, the 3DES requirements are quite specific, so for my special case, the DESede / CBC / PKCS5Padding combinations do not solve the problem. After some comparative testing of my results against some 3DES calculators designed for the financial world, I found that the value "DESede / ECB / Nopadding" is more suitable for a specific task.

Here is a demo implementation of my TripleDes class (using the Bouncy Castle provider)

 import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * * @author Jose Luis Montes de Oca */ public class TripleDesCipher { private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/Nopadding"; private static String ALGORITHM = "DESede"; private static String BOUNCY_CASTLE_PROVIDER = "BC"; private Cipher encrypter; private Cipher decrypter; public TripleDesCipher(byte[] key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { Security.addProvider(new BouncyCastleProvider()); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); encrypter.init(Cipher.ENCRYPT_MODE, keySpec); decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); decrypter.init(Cipher.DECRYPT_MODE, keySpec); } public byte[] encode(byte[] input) throws IllegalBlockSizeException, BadPaddingException { return encrypter.doFinal(input); } public byte[] decode(byte[] input) throws IllegalBlockSizeException, BadPaddingException { return decrypter.doFinal(input); } } 
+8
Apr 15 2018-12-12T00:
source share

Here the very simple static encryption / decryption class biased at Bouncy Castle does not include the example of Jose Luis Montes de Oka add-ons. This one uses โ€œDESede / ECB / PKCS7Paddingโ€, so I donโ€™t have to worry about manual filling.

 package com.zenimax.encryption; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * * @author Matthew H. Wagner */ public class TripleDesBouncyCastle { private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/PKCS7Padding"; private static String ALGORITHM = "DESede"; private static String BOUNCY_CASTLE_PROVIDER = "BC"; private static void init() { Security.addProvider(new BouncyCastleProvider()); } public static byte[] encode(byte[] input, byte[] key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { init(); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); Cipher encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); encrypter.init(Cipher.ENCRYPT_MODE, keySpec); return encrypter.doFinal(input); } public static byte[] decode(byte[] input, byte[] key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { init(); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); Cipher decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); decrypter.init(Cipher.DECRYPT_MODE, keySpec); return decrypter.doFinal(input); } }
package com.zenimax.encryption; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * * @author Matthew H. Wagner */ public class TripleDesBouncyCastle { private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/PKCS7Padding"; private static String ALGORITHM = "DESede"; private static String BOUNCY_CASTLE_PROVIDER = "BC"; private static void init() { Security.addProvider(new BouncyCastleProvider()); } public static byte[] encode(byte[] input, byte[] key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { init(); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); Cipher encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); encrypter.init(Cipher.ENCRYPT_MODE, keySpec); return encrypter.doFinal(input); } public static byte[] decode(byte[] input, byte[] key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { init(); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); Cipher decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); decrypter.init(Cipher.DECRYPT_MODE, keySpec); return decrypter.doFinal(input); } } 
+2
Jul 06 '12 at 18:37
source share
 import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import java.util.Base64; import java.util.Base64.Encoder; /** * * @author shivshankar pal * * this code is working properly. doing proper encription and decription note:- it will work only with jdk8 * * */ public class TDes { private static byte[] key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; private static byte[] keyiv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; public static String encode(String args) { System.out.println("plain data==> " + args); byte[] encoding; try { encoding = Base64.getEncoder().encode(args.getBytes("UTF-8")); System.out.println("Base64.encodeBase64==>" + new String(encoding)); byte[] str5 = des3EncodeCBC(key, keyiv, encoding); System.out.println("des3EncodeCBC==> " + new String(str5)); byte[] encoding1 = Base64.getEncoder().encode(str5); System.out.println("Base64.encodeBase64==> " + new String(encoding1)); return new String(encoding1); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static String decode(String args) { try { System.out.println("encrypted data==>" + new String(args.getBytes("UTF-8"))); byte[] decode = Base64.getDecoder().decode(args.getBytes("UTF-8")); System.out.println("Base64.decodeBase64(main encription)==>" + new String(decode)); byte[] str6 = des3DecodeCBC(key, keyiv, decode); System.out.println("des3DecodeCBC==>" + new String(str6)); String data=new String(str6); byte[] decode1 = Base64.getDecoder().decode(data.trim().getBytes("UTF-8")); System.out.println("plaintext==> " + new String(decode1)); return new String(decode1); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "u mistaken in try block"; } private static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) { try { Key deskey = null; DESedeKeySpec spec = new DESedeKeySpec(key); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede/ CBC/PKCS5Padding"); IvParameterSpec ips = new IvParameterSpec(keyiv); cipher.init(Cipher.ENCRYPT_MODE, deskey, ips); byte[] bout = cipher.doFinal(data); return bout; } catch (Exception e) { System.out.println("methods qualified name" + e); } return null; } private static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) { try { Key deskey = null; DESedeKeySpec spec = new DESedeKeySpec(key); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede/ CBC/NoPadding");//PKCS5Padding NoPadding IvParameterSpec ips = new IvParameterSpec(keyiv); cipher.init(Cipher.DECRYPT_MODE, deskey, ips); byte[] bout = cipher.doFinal(data); return bout; } catch (Exception e) { System.out.println("methods qualified name" + e); } return null; } } 
0
Aug 20 '14 at 5:35
source share



All Articles