user8231819
user8231819

Reputation:

How can we do Triple Decryption in java?

I am using a MOL API for VOUCHER recharges. Which returns a PIN number in response is successful. That PIN number will be an encrypted text and I need to triple decrypt it!

I contacted the API support, They provided with the code below:

byte[] PinBytes = Base64.decodeBase64(encryptedText.getBytes("utf-8"));
byte[] VectorBytes = Base64.decodeBase64(vectorKey.getBytes("utf-8"));
byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8")); 
TripleDESProvider = CreateTripleDESCryptographicProvider(VectorBytes, SecretKeyBytes)
    DecryptedBytes = TripleDESProvider.Decrypt(PinBytes) 

Here VectorBytes and SecretKeyBytes are security keys provided by them and PinBytes are the response PIN number which is encrypted.

I googled while I was not able to get a correct solution with these three parameters. Any help, please?

I tried this:

try
        {
            String encryptedText = "FN0hbSrVzkqhe+w2rQefAQ==";
            String vectorKey = "7EsBtzAJjMg=";
            //32 bit key
            String secretKey = "08061052989102040806105298910204";
            byte[] PinBytes = Base64.decodeBase64(encryptedText.getBytes("utf-8"));
            byte[] VectorBytes = Base64.decodeBase64(vectorKey.getBytes("utf-8"));
            byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8"));
            final MessageDigest md = MessageDigest.getInstance("md5");
            final byte[] digestOfPassword = md.digest(SecretKeyBytes);
            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(VectorBytes);
            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(PinBytes);

            System.out.println(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();
        }

Error is Invalid KEY

The document they provide is;

Convert Encrypted Pin into Byte Array from Base64 format

PinBytes = ConvertFromBase64String ("FN0hbSrVzkqhe+w2rQefAQ==")

As Vector Key and Secret Key are provided in Base64 format, thus we need to convert both data into Byte Array as well

VectorBytes = ConvertFromBase64String ("xxxxxxxxx") 
SecretKeyBytes = ConvertFromBase64String ("xxxxxxxxxxxx")

Please create your Triple DES Cryptographic Provider and set your IV byte array and Secret Key byte array into your Provider.

TripleDESProvider = CreateTripleDESCryptographicProvider(VectorBytes, SecretKeyBytes)

Please invokes Triple DES Provider decrypt method.

DecryptedBytes = TripleDESProvider.Decrypt(PinBytes)

Finally convert back decrypted bytes back to string.

ConvertToString(DecryptedBytes)

The result should be 8157151550.

Upvotes: 2

Views: 233

Answers (2)

user8231819
user8231819

Reputation:

Finally, I Got this answer with same provided secretKey!!

try
        {
            byte[] PinBytes = Base64.decodeBase64(encryptedText);
            byte[] VectorBytes = Base64.decodeBase64(vectorKey);
            byte[] SecretKeyBytes = Base64.decodeBase64(secretKey);
         // initialize the vector with the one you receive               
            IvParameterSpec spec = new IvParameterSpec(VectorBytes);

            // create the key. DESede should be correct, but if it doesn't work try also with DES
            Key key = new SecretKeySpec(SecretKeyBytes, "DESede");

            // Initialize the cipher
            Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");

            // decrypt the string
            c.init(Cipher.DECRYPT_MODE, key, spec);
            byte[] decodedDecryptedBytes = c.doFinal(PinBytes);
            return new String(decodedDecryptedBytes, "UTF-8");      
        }
        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("InvalidKeyException : Invalid Key"); }
        catch (BadPaddingException e) { System.out.println("BadPaddingException : Invalid Key");}
        catch (IllegalBlockSizeException e) { System.out.println("IllegalBlockSizeException : Invalid Key");}
        catch (UnsupportedEncodingException e) { System.out.println("UnsupportedEncodingException : Invalid Key");}     
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;

The Mistake was doing this:

 byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8"));

I don't know why this happens! But by removing that I got the answer!!

Upvotes: 0

amicoderozer
amicoderozer

Reputation: 2144

I am not sure if this is the right approach but with AES encryption it works. They provided you the vector, use it to initialize the IVParameterSpec, then create Key object and Cipher instance:

// this is the encripted text
byte[] PinBytes = Base64.decodeBase64(encryptedText.getBytes("utf-8"));

byte[] VectorBytes = Base64.decodeBase64(vectorKey.getBytes("utf-8"));

byte[] SecretKeyBytes = Base64.decodeBase64(secretKey.getBytes("utf-8")); 

// initialize the vector with the one you receive               
IvParameterSpec spec = new IvParameterSpec(VectorBytes);

// create the key. DESede should be correct, but if it doesn't work try also with DES
Key key = new SecretKeySpec(SecretKeyBytes, "DESede");

// Initialize the cipher
Cipher c = Cipher.getInstance("DESede/CBC/PKCS5Padding");

// decrypt the string
c.init(Cipher.DECRYPT_MODE, key, spec);
byte[] decodedDecryptedBytes = c.doFinal(PinBytes);

Base64 object i use is from apache common codec library, but you can use the library you want.

Upvotes: 1

Related Questions