Php 没有mcrypt的Sagepay集成

Php 没有mcrypt的Sagepay集成,php,openssl,mcrypt,Php,Openssl,Mcrypt,我希望在这里使用他们的指导与Sagepay/Opayo表单集成: Sagepay现在已经停止支持SDK,这意味着我必须从这里找到2013年的实用程序集: 我正试图从mcrypt迁移到openssl\u encrypt,但似乎无法复制所需的结果 有两个功能在发挥作用: static protected function addPKCS5Padding($input) { $blockSize = 16; $padd = ""; // Pad input to an eve

我希望在这里使用他们的指导与Sagepay/Opayo表单集成:

Sagepay现在已经停止支持SDK,这意味着我必须从这里找到2013年的实用程序集:

我正试图从mcrypt迁移到
openssl\u encrypt
,但似乎无法复制所需的结果

有两个功能在发挥作用:

static protected function addPKCS5Padding($input)
{
$blockSize = 16;
$padd = "";

// Pad input to an even block size boundary.
$length = $blockSize - (strlen($input) % $blockSize);
for ($i = 1; $i <= $length; $i++)
{
$padd .= chr($length);
}

return $input . $padd;
}

static public function encryptAes($string, $key)
{
// AES encryption, CBC blocking with PKCS5 padding then HEX encoding.
// Add PKCS5 padding to the text to be encypted.
$string = self::addPKCS5Padding($string);

// AH updated as mcrypt is now deprecated! 2020
$cipher = 'AES-128-CBC';
$ivsize = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivsize);

$crypt = openssl_encrypt($string,$cipher,$key,0,$iv);

// Perform hex encoding and return.
return "@" . strtoupper(bin2hex($crypt));
}
静态保护函数addPKCS5Padding($input)
{
$blockSize=16;
$padd=“”;
//将输入填充到偶数块大小边界。
$length=$blockSize-(strlen($input)%$blockSize);
对于($i=1;$i
  • openssl\u encrypt
    默认情况下应用PKCS7填充,因此不再需要
    addPKCS5Padding
    方法
  • mcrypt\u encrypt
    code iv=中使用了密钥,因此不能为代码等价生成随机iv
  • openssl\u encrypt
    中,必须将标志
    openssl\u RAW\u DATA
    作为第四个参数应用,否则数据将返回Base64编码
通过这些更改,
openssl\u encrypt
代码产生与
mcrypt\u encrypt
代码相同的结果:

<?php
function encryptAes($string, $key)
{
    //$string = self::addPKCS5Padding($string);                                     // don't pad explicitly
 
    $cipher = 'AES-128-CBC';                                                        
    //$ivsize = openssl_cipher_iv_length($cipher);
    //$iv = openssl_random_pseudo_bytes($ivsize);                                   // mcrypt_encrypt code: iv = key

    $crypt = openssl_encrypt($string,$cipher,$key,OPENSSL_RAW_DATA,$key);           // use raw data

    return "@" . strtoupper(bin2hex($crypt));
}

$plain = "VendorTxCode=TxCode-1310917599-223087284&Amount=36.95&Currency=GBP&Description=description&CustomerName=Fname Surname&CustomerEMail=customer@example.com&BillingSurname=Surname&BillingFirstnames=Fname&BillingAddress1=BillAddress Line 1&BillingCity=BillCity&BillingPostCode=W1A 1BL&BillingCountry=GB&BillingPhone=447933000000&DeliveryFirstnames=Fname&DeliverySurname=Surname&DeliveryAddress1=BillAddress Line 1&DeliveryCity=BillCity&DeliveryPostCode=W1A 1BL&DeliveryCountry=GB&DeliveryPhone=447933000000&SuccessURL=https://example.com/success&FailureURL=https://example.com/failure";
$key = "55a51621a6648525";
print(encryptAes($plain, $key));
?>

@Topaco回答得很好。这是一个额外的位(与问题无关),在进行Sagepay集成时,您还需要解密函数来验证支付/回调。这是您可以使用的函数

    function decrypytAES($string, $key) {
        $cipher = 'AES-128-CBC';
        $strIn = hex2bin(substr($strIn, 1));
        return openssl_decrypt($strIn, $cipher, $key, OPENSSL_RAW_DATA, $key);
    }

由于random IV,即使使用相同的明文和密钥,每次加密都会生成不同的密文。啊!好吧-我不确定他们的系统将如何处理,所以我将按原样进行尝试。谢谢!Sagepay给我一个500错误,说“由于服务器遇到意外情况,请求未成功。”。我不确定这是我的目的还是他们的目的,我已经给他们发了电子邮件,但一旦我确认这是可行的,我会将其标记为答案。我发布的代码在我的机器上生成的密文与中的相应方法相同(假设相同的密钥和明文)。您是否验证了您的环境中是否也存在这种情况?如果是,您可能需要进行调整,而不仅仅是简单地用openssl替换mcrypt(尽管遗憾的是,我不知道是哪一种)。