How to Use 3Des Encryption/Decryption in Java

How do I use 3DES encryption/decryption in Java?

Your code was fine except for the Base 64 encoding bit (which you mentioned was a test), the reason the output may not have made sense is that you were displaying a raw byte array (doing toString() on a byte array returns its internal Java reference, not the String representation of the contents). Here's a version that's just a teeny bit cleaned up and which prints "kyle boon" as the decoded 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");
}
}

3des encrypting/decrypting of file java

  1. The usage

    byte[] fileByteArray = new byte[fileInputStream.available()];

    is specifically warned against in the Javadoc: " It is never correct to use the return value of this method to allocate a buffer intended to hold all data in this stream."

    Files should be processed a record or a buffer at a time.

  2. The line:

    fileInputStream.read(fileByteArray);

    isn't guaranteed to fill the buffer. You have to check the return value: for -1, meaning end of file, or > 0, meaning the number of bytes that were actually transferred. See the Javadoc.

  3. Similarly

    while (objectInputStream.available() != 0) {

    is not a valid test for end of stream. You should call readObject() until it throws EOFException.

Decrypting value in 3Des using Java

You are making it more complex than you need to with the SecretKeyFactory, etc. But the main problem is that you aren't converting hexadecimal numbers correctly.

class TripleDES
{

private final String key;

public static void main(String... args)
throws Exception
{
TripleDES td = new TripleDES("1032FD2CD64A9D7FA4D061F76B04BFEA");
String decrypted = td.decrypt("AC9C5A46A63FC9EA");
System.out.println("expecting: 04286EDDFDEA6BD7");
System.out.println("found: " + decrypted);
}

TripleDES(String key)
{
this.key = key;
}

public String decrypt(String input)
throws Exception
{
byte[] tmp = h2b(this.key);
byte[] key = new byte[24];
System.arraycopy(tmp, 0, key, 0, 16);
System.arraycopy(tmp, 0, key, 16, 8);
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "DESede"));
byte[] plaintext = cipher.doFinal(h2b(input));
return b2h(plaintext);
}

private static byte[] h2b(String hex)
{
if ((hex.length() & 0x01) == 0x01)
throw new IllegalArgumentException();
byte[] bytes = new byte[hex.length() / 2];
for (int idx = 0; idx < bytes.length; ++idx) {
int hi = Character.digit((int) hex.charAt(idx * 2), 16);
int lo = Character.digit((int) hex.charAt(idx * 2 + 1), 16);
if ((hi < 0) || (lo < 0))
throw new IllegalArgumentException();
bytes[idx] = (byte) ((hi << 4) | lo);
}
return bytes;
}

private static String b2h(byte[] bytes)
{
char[] hex = new char[bytes.length * 2];
for (int idx = 0; idx < bytes.length; ++idx) {
int hi = (bytes[idx] & 0xF0) >>> 4;
int lo = (bytes[idx] & 0x0F);
hex[idx * 2] = (char) (hi < 10 ? '0' + hi : 'A' - 10 + hi);
hex[idx * 2 + 1] = (char) (lo < 10 ? '0' + lo : 'A' - 10 + lo);
}
return new String(hex);
}

}

Decrypt a data by 3DES-128 bits CBC Mode (padding zero)) using java

Since you want to try to carrying out the 3DES-128 bits CBC Mode (padding zero) method, try out this git https://github.com/meshileya/dukpt to use in getting the plaintext from the ciphertext.

Since you already have your BDK and KSN, just try to run the method below.

 public static void main(String[] args) {
try {
String theksn = "This should be your KSN";
String encrypted = "This should be the encrypted data";
String BDK = "The BDK you mentioned up there";

tracking= DukptDecrypt.decrypt(theksn, BDK, encrypted);

System.out.print("PlainText"+ tracking);
}catch (Exception e){System.out.print(e);}

}


Related Topics



Leave a reply



Submit