I'm having issues to decrypt the ciphered text using BouncyCastle- the algorithm is AES-256CBC with PKC7 padding.
The PHP code that easily decrypts the data looks like that:
$output = 'WwBOU6s8DaMWmYdctBJwfuoujFgVygBUjhsbdf8eWqQ='; /* The encrypted return that we are going to decrypt */
$date = '2021-05-26 14:00:00'; /* The date which must correspond to the exact date transmitted during the call */
$private_key = '7X9gx9E3Qx4EiUdB63nc'; /* Your private key obtained when you created your API access */
$key = hash('sha256' , $date . $private_key); /* Creation of the key by concatenating the date and the private key */
$iv = mb_strcut(hash('sha256', hash('sha256', $private_key)), 0, 16,); /* Creation of the initialization vector (2x hash of the private key) by taking 16 bytes */
echo (openssl_decrypt($output, 'aes-256-cbc', $key, false, $iv)); /* Display the return using openssl_decrypt */
My attempt to achieve the same in Java look as follows:
public class Aes {
public static void main(String[] args) throws Exception {
String date = "2021-05-26 14:00:00";
String private_key = "7X9gx9E3Qx4EiUdB63nc";
String composite = date+private_key;
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(composite.getBytes());
byte[] stringHash = messageDigest.digest();
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(private_key.getBytes());
MessageDigest md2 = MessageDigest.getInstance("SHA-256");
md2.update(md.digest());
String encryptedText = "WwBOU6s8DaMWmYdctBJwfuoujFgVygBUjhsbdf8eWqQ=";
/*
* Register BC provider dynamically, BC needed for AES 256.
* AES 256 is Rijndael 128 using 32 byte key and 16 byte IV.
*/
Security.addProvider(new BouncyCastleProvider());
byte[] skey = stringHash;
//byte[] ivec = new byte[16]; // AES 256 use 16 byte IVEC
byte[] ivec=copyOfRange(md2.digest(), 0,16);
byte[] encrypted = javax.xml.bind.DatatypeConverter.parseBase64Binary(encryptedText);
if (encrypted.length % 16 != 0) {
throw new IllegalArgumentException("because has padding, input must be multiple of 16, length=" + encrypted.length);
}
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(skey), ivec);
aes.init(false, ivAndKey); // false for decryption
int minSize = aes.getOutputSize(encrypted.length);
byte[] outBuf = new byte[minSize];
int length1 = aes.processBytes(encrypted, 0, encrypted.length, outBuf, 0);
int length2 = aes.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] decrypted = new byte[actualLength];
System.arraycopy(outBuf, 0, decrypted, 0, actualLength);
String decryptedString = new String(decrypted, "UTF-8");
System.out.println("<[" + decryptedString + "]>");
}
}
The problem is that I get the exception and I can't resolve it:
Exception in thread "main" org.bouncycastle.crypto.InvalidCipherTextException: pad block corrupted
at org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(Unknown Source)
at org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(Unknown Source)
at Aes.main(Aes.java:68)
I'm not sure where the issue is, is it when I tried to do the 2xhash of the private key or somewhere else.
Is there anyone capable of helping me out ?