We use the Sage Pay / Opayo form integration to pass customer orders to Sage Pay for payment, then to process the report that comes back. Sage Pay's example code relies on the PHP mcrypt functions which are no longer supported from PHP 7.2, so we need to update the scripts to OpenSSL.
Encryption was covered by a great post here: Upgrade mcrypt to OpenSSL encryption in SagePay form
- this works fine for me:
function encryptAes_new ($string, $key) {
$key = str_pad($key,16,"\0"); # if supplied key is, or may be, less than 16 bytes
$crypt = openssl_encrypt($string, 'aes-128-cbc', $key, OPENSSL_RAW_DATA, $key);
// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
...but I can't find a matching code to fix the decrypt function.
The current code is:
function decryptAes($strIn, $password)
{
// HEX decoding then AES decryption, CBC blocking with PKCS5 padding.
// Use initialization vector (IV) set from $str_encryption_password.
$strInitVector = $password;
// Remove the first char which is @ to flag this is AES encrypted and HEX decoding.
$hex = substr($strIn, 1);
$strIn = pack('H*', $hex);
// Perform decryption with PHP's MCRYPT module.
$string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC, $strInitVector);
return removePKCS5Padding($string);
}
Could anyone help with an OpenSSL version, please?
When decrypting, the
@prefix must first be removed, then hex decoding must be done, and finally decryption can be performed.openssl_decrypt()implicitly removes the padding, so that no explicit removal is required. This is implemented indecryptAes_new()below:which produces the output:
Checking the length of the plaintext after decryption, 43 bytes, shows that the padding has been automatically removed.