2

我正在尝试使用“表单集成”方法将 SagePay 支付网关集成到网站中。

基本上,表单集成方法通过在网页中插入表单并将信息发布到 SagePay 的服务器,只要选择表单的提交按钮即可。在将信息发送到 SagePay 的服务器之前,必须使用 AES/CBC/PKCS#5 算法对其进行加密,然后再进行 Base 64 编码。

我有加密的基本知识,但我没有在 PHP 中使用它的经验。谁能帮我在 PHP 中制定 AES/CBC/PKCS#5 算法吗?

到目前为止,这是我的努力:

$CRYPT = "Text Goes Here";

$blocksize = 16;//Does 16 Refer To 16 Bytes Or 16 Bits? 16 Bytes = 128 Bits.
$cryptLength = strlen($CRYPT);
$cryptLengthModuloBlocksize = $cryptLength % $blocksize;
$pad = $blocksize - $cryptLengthModuloBlocksize;
$padString = str_repeat(chr($pad), $pad);
$CRYPT = $CRYPT . $padString;

$encryptionPassword = 'password';
$Encrypted_CRYPT = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $encryptionPassword, $CRYPT, MCRYPT_MODE_CBC);

$Base64_Encrypted_CRYPT = base64_encode($Encrypted_CRYPT);

echo    "<form action = 'https://test.sagepay.com/gateway/service/vspform-register.vsp' method = 'POST'>

            <input type = 'hidden' name = 'VPSProtocol' value = '3.00' />//
            <input type = 'hidden' name = 'TxType' value = 'PAYMENT' />
            <input type = 'hidden' name = 'Vendor' value = 'vendorName' />
            <input type = 'hidden' name = 'Crypt' value = '" . $Base64_Encrypted_CRYPT . "' />
            <input type= 'submit' value = 'Submit'>

        </form>";

任何帮助深表感谢。

4

4 回答 4

8

这是使用 Sagepay 的表单集成的 AES/CBC/PKCS#5 的工作实现您将需要安装 mcrypt。sp_encryption 是加密密钥的定义。

/**
* @param string $data - the key=value pairs separated with & 
* @return string
*/
protected function encode_data($data) {
    $strIn = $this->pkcs5_pad($data);
    $strCrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, sp_encryption, $strIn, MCRYPT_MODE_CBC, sp_encryption);
    return "@" . bin2hex($strCrypt);
}

/**
* @param string $data - crypt response from Sagepay
* @return string
*/
protected function decode_data($data) {
    if (substr($data, 0, 1) == "@") {
        $strIn = hex2bin(substr($data, 1));
        return $this->pkcs5_unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, sp_encryption, $strIn, MCRYPT_MODE_CBC, sp_encryption));
    }
    return '';
}

protected function pkcs5_pad($text) {
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $pad = $size - (strlen($text) % $size);
    return $text . str_repeat(chr($pad), $pad);
}

protected function pkcs5_unpad($text) {
    $pad = ord($text{strlen($text) - 1});
    if ($pad > strlen($text)) return false;
    if (strspn($text, $text{strlen($text) - 1}, strlen($text) - $pad) != $pad) {
        return false;
    }
    return substr($text, 0, -1 * $pad);
}

附带说明一下,确保您使用的 VPSProtocol 是“3.00”而不是 3,而不是 3.0,因为这些不起作用!

希望这有助于 sagepay 尽快发布一些官方 PHP 文档。

于 2014-01-30T11:41:54.220 回答
5

是的,没关系。(一旦我们有了 v3.00 的 PHP 工具包,我们就会在我们的网站上展示它)。

希望以下内容对您有所帮助。

例子:

使用 Base64 编码的 AES 加密 AES 加密,使用 PKCS5 填充然后 HEX 编码的 CBC 阻塞

//** Wrapper function do encrypt an encode based on strEncryptionType setting **
function encryptAndEncode($strIn) {

global $strEncryptionType
      ,$strEncryptionPassword;

{
    //** AES encryption, CBC blocking with PKCS5 padding then HEX encoding **

    //** use initialization vector (IV) set from $strEncryptionPassword
    $strIV = $strEncryptionPassword;

    //** add PKCS5 padding to the text to be encypted
    $strIn = addPKCS5Padding($strIn);

    //** perform encryption with PHP's MCRYPT module
    $strCrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $strEncryptionPassword, $strIn, MCRYPT_MODE_CBC, $strIV);

    //** perform hex encoding and return
    return "@" . bin2hex($strCrypt);
}
}


//** Wrapper function do decode then decrypt based on header of the encrypted field **
function decodeAndDecrypt($strIn) {

global $strEncryptionPassword;

if (substr($strIn,0,1)=="@") 
{
    //** HEX decoding then AES decryption, CBC blocking with PKCS5 padding  **

    //** use initialization vector (IV) set from $strEncryptionPassword
    $strIV = $strEncryptionPassword;

    //** remove the first char which is @ to flag this is AES encrypted
    $strIn = substr($strIn,1); 

    //** HEX decoding
    $strIn = pack('H*', $strIn);

    //** perform decryption with PHP's MCRYPT module
    return removePKCS5Padding(
        mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $strEncryptionPassword, $strIn, MCRYPT_MODE_CBC, $strIV));
} 

}
于 2013-11-26T19:07:36.240 回答
2

您是否使用 PKCS5 填充,然后使用 HEX 编码,因为我们的旧 PHP 工具包使用了这个。

您可能想查看以前的帖子来比较您发送的内容。它使用的是较旧的协议 v2.23 和 XOR。如果您使用我们的新协议,您将使用 v3.00 和 AES。

如果您想发送电子邮件至 feedback@sagepay.com,我们可以进一步讨论。请引用此论坛帖子 URL。

贤者支付支持

于 2013-11-26T14:28:12.963 回答
2

您可以在此处查看有效的 v3 示例:https ://github.com/tolzhabayev/sagepayForm-php

于 2013-12-22T12:45:14.917 回答