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

2.9k Views Asked by At

In the process of decrypting an encrypted data, i am having a little challenge with it. I will be so glad if anyone can help putting me through.

Although, i have already studied the algorithm in carrying out this operation, since i am to get my data from a device, which already has its Base Derivation Key(BDK), Initially loaded key serial number and the initially loaded pin entry device key.

In the documentation that was been given, we have the Initially loaded key serial number, data encryption key variant and the track 2 Data (which is in plaintext).

In this example, i was made to know that they actually used a 3DES-128 bits CBC Mode (padding zero) method.

my question now is, how was the plaintext gotten from the encrypted data. I will be so glad, if anyone can put me through (stating the flow or the algorithm to use in decrypting this data).

Will so much appreciate your time.

2

There are 2 best solutions below

0
On BEST ANSWER

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

    }
3
On

One of the more stupid things about the Oracle implementation is that the SecretKeyFactory does not support DES ABA keys, also known as "two-key" DES keys.

These keys for triple-DES operation consists of a single DES key A, followed by single DES key B. Key A is used both for the first and last iteration of DES within DES EDE (Encrypt-Decrypt-Encrypt).

If you stay within software you can create a method to create such keys. The problem is that the resulting keys actually have 192 bits, which is simply not correct - it makes it impossible to distinguish between the key sizes.

Anyway, the following code can be used to generate DES ABA keys:

private static final int DES_KEY_SIZE_BYTES = 64 / Byte.SIZE;
private static final int DES_ABA_KEY_SIZE_BYTES = 2 * DES_KEY_SIZE_BYTES;
private static final int DES_ABC_KEY_SIZE_BYTES = 3 * DES_KEY_SIZE_BYTES;

public static SecretKey createDES_ABAKey(byte[] key) {
    if (key.length != DES_ABA_KEY_SIZE_BYTES) {
        throw new IllegalArgumentException("128 bit key argument with size expected (including parity bits.)");
    }
    try {
        byte[] desABCKey = new byte[DES_ABC_KEY_SIZE_BYTES];
        System.arraycopy(key, 0, desABCKey, 0, DES_ABA_KEY_SIZE_BYTES);
        System.arraycopy(key, 0, desABCKey, DES_ABA_KEY_SIZE_BYTES, DES_KEY_SIZE_BYTES);
        SecretKeySpec spec = new SecretKeySpec(desABCKey, "DESede");
        SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
        SecretKey desKey = factory.generateSecret(spec);
        return desKey;
    } catch (GeneralSecurityException e) {
        throw new RuntimeException("DES-EDE ABC key factory not functioning correctly", e);
    }
}

OK, so that leaves us with the CBC encryption (no padding, and zero IV):

private static final byte[] ENCRYPTION_KEY = Hex.decode("448D3F076D8304036A55A3D7E0055A78");
private static final byte[] PLAINTEXT = Hex.decode("1234567890ABCDEFFEDCBA0987654321");

public static void main(String[] args) throws Exception {
    SecretKey desABAKey = createDES_ABAKey(ENCRYPTION_KEY);
    Cipher desEDE = Cipher.getInstance("DESede/CBC/NoPadding");
    IvParameterSpec zeroIV = new IvParameterSpec(new byte[desEDE.getBlockSize()]);
    desEDE.init(Cipher.ENCRYPT_MODE, desABAKey, zeroIV);
    byte[] ciphertext = desEDE.doFinal(PLAINTEXT);
    System.out.println(Hex.toHexString(ciphertext));
}

I've used the Bouncy Castle hexadecimal codec, but other hexadecimal codecs can also be used.