Link to home
Start Free TrialLog in
Avatar of pmsguy
pmsguy

asked on

Java decrypt error for 15 digit credit card number

My Java decrypt code is NOT decrypting a 15 digit credit card number properly.

When the credit card number is decrypted I get 15 digits and the ^@

For example: 123456789012345^@

16 digit credit card numbers are decrypting properly.

public String decrypt(byte[] buffer)
  {
    String out = null;
    if(buffer==null) return null;
    if(buffer.length==0) return null;

    try
    {
      DESedeKeySpec keyspec = new DESedeKeySpec(baseKey);
      SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
      SecretKey key = keyfactory.generateSecret(keyspec);

      // Create and initialize the decryption engine
      Cipher cipher = Cipher.getInstance(keyAlg);
      cipher.init(Cipher.DECRYPT_MODE, key);

      byte[] zbuf = cipher.doFinal(buffer);
      out = new String(zbuf);
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    return out;
  }

Open in new window

Avatar of Mick Barry
Mick Barry
Flag of Australia image

>       out = new String(zbuf);


try:


      out = new String(zbuf, "UTF-8");
Try
byte[] tmp = new byte[16];
System.arraycopy(buffer, 0, tmp, 0, 16];
out = new String(cipher.doFinal(tmp));

Open in new window

Avatar of pmsguy
pmsguy

ASKER

Where in the code should your snippet be placed?

byte[] tmp = new byte[16];
System.arraycopy(buffer, 0, tmp, 0, 16];
out = new String(cipher.doFinal(tmp));
Replace lines 17 and 18 with it
Avatar of pmsguy

ASKER

Neither for the above suggestions worked.

I am still getting a 16th char if the credit card is 15 characters.

Please advice,  I need to get this fixed ASAP as it is affecting our credit card billing.
I don't have much time at the moment, but what is the value of 'keyAlg'?
ASKER CERTIFIED SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
check the source of your byte array, the problem may be there
Avatar of pmsguy

ASKER

Please explain in more detail "check the source of your byte array, the problem may be there"

NOTE: The value of keyAlg is "DESede/ECB/NoPadding"

The code did not fix the issue:

    public static byte[] padDESKey(byte[] key) {
      byte[] result = new byte[24];
      System.arraycopy(key, 0, result, 0, Math.min(key.length, result.length));
      return result;
    }

To be explicit, where in my code should baseKey be padded/truncated
Avatar of pmsguy

ASKER

It appears the output is padded with "^@" and must be a multiple of 8

Therefore my code generates the following encrypted to decrypted value

Encrypted --> Decrypted
1234 --> 1234^@^@^@^@
12345 --> 12345^@^@^@
123456 --> 123456^@^@
1234567-->1234567^@
12345678 --> 12345678

So how do I truncate the Decrypted value accordingly?  That is, if the encrypted value is supposed to be 15 chars then how do I make the decrypted value 15 chars with the algorithm?
>>The code did not fix the issue:

Please post the code where you used it. It works for me
Avatar of pmsguy

ASKER

See line DESedeKeySpec keyspec = new DESedeKeySpec( padDESKey(baseKey) );

where I added your function padDESKey

This is line 9 in the above code in the initial questions posted
That seems OK. So i'm not sure where it's going wrong. Run the following:
import javax.crypto.*;
import javax.crypto.spec.*;


public class DesCrypDecryp {
    static final String keyAlg = "DESede/ECB/NoPadding";
    static final byte[] baseKey = { 1, 2, 3, 4 };

    public static void main(String[] args) throws Exception {
	DesCrypDecryp dcd = new DesCrypDecryp();
	byte[] buf = new byte[256];
	byte[] plainText = args[0].getBytes();

	System.arraycopy(plainText, 0, buf, 0, plainText.length);

	byte[] cipherText = dcd.encrypt(buf);

	System.out.printf("Plaintext was '%s'\n", dcd.decrypt(cipherText));
    }

    public static byte[] padDESKey(byte[] key) {
        byte[] result = new byte[24];
        System.arraycopy(key, 0, result, 0, Math.min(key.length, result.length));
        return result;
    }

    public byte[] encrypt(byte[] buffer) {
        byte[] result = null;

        if (buffer == null) {
            return null;
        }

        if (buffer.length == 0) {
            return null;
        }

        try {
            DESedeKeySpec keyspec = new DESedeKeySpec(padDESKey(baseKey));
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
            SecretKey key = keyfactory.generateSecret(keyspec);

            // Create and initialize the decryption engine
            Cipher cipher = Cipher.getInstance(keyAlg);
	    byte[] k = padDESKey(baseKey);
            cipher.init(Cipher.ENCRYPT_MODE, key);

            result = cipher.doFinal(buffer);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    public String decrypt(byte[] buffer) {
        String out = null;

        if (buffer == null) {
            return null;
        }

        if (buffer.length == 0) {
            return null;
        }

        try {
            DESedeKeySpec keyspec = new DESedeKeySpec(padDESKey(baseKey));
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
            SecretKey key = keyfactory.generateSecret(keyspec);

            // Create and initialize the decryption engine
            Cipher cipher = Cipher.getInstance(keyAlg);
            cipher.init(Cipher.DECRYPT_MODE, key);

            byte[] zbuf = cipher.doFinal(buffer);
            out = new String(zbuf);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return out;
    }
}

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pmsguy

ASKER

Thanks for the effort.  However, none of these solved my problem.