Reputation:
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
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
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