Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
265 views
in Technique[技术] by (71.8m points)

protocols - Sage Pay v3.00 Integration

Can anyone help me incorporate the Sagepay v3.00 AES/CBC/PKCS#5 algorithm (encryption) into the following file. I'm really struggling to understand how to include so that customer data is encrypted to the new standard and then decrypted on the way back. Using Sagepay Form with a very old version of cs-cart, though have successfully managed to upgrade from version 2.22 to 2.23, but Sagepay are pulling all support from July.

Not sure how much of this script is relevant to the encryption:

<?php

if ( !defined('IN_CSCART') ) { die('Access denied'); }

if (defined('PAYMENT_NOTIFICATION')) {  

// Get the password
$payment_id=db_get_field("SELECT $db_tables[payments].payment_id FROM $db_tables[payments] LEFT JOIN $db_tables[payment_processors] ON $db_tables[payment_processors].processor_id = $db_tables[payments].processor_id WHERE $db_tables[payment_processors].processor_script='protx_form.php'");
$processor_data = fn_get_payment_method_data($payment_id);

$result = "&".simpleXor(base64Decode($_REQUEST['crypt']), $processor_data["params"]["password"])."&";

preg_match("/Status=(.+)&/U", $result, $a);
if(trim($a[1]) == "OK") {
    $pp_response['order_status'] = ($processor_data["params"]["transaction_type"] == 'PAYMENT') ? 'P' : 'O';
    preg_match("/TxAuthNo=(.+)&/U", $result, $authno);
    $pp_response["reason_text"] = "AuthNo: ".$authno[1];
    preg_match("/VPSTxID={(.+)}/U", $result, $transaction_id);
    $pp_response["transaction_id"] = @$transaction_id[1];
} else {
    $pp_response['order_status'] = 'F';
    preg_match("/StatusDetail=(.+)&/U", $result, $stat);
    $pp_response["reason_text"] = "Status: ".trim($stat[1])." (".trim($a[1]).") ";
}
preg_match("/AVSCV2=(.*)&/U", $result, $avs);
if(!empty($avs[1])) {
    $pp_response['descr_avs'] = $avs[1];
}
include $payment_files_dir.'payment_cc_complete.php';
fn_order_placement_routines($order_id);

}
else
{
    global $http_location, $b_order, $_total_back;

    $post_address = ($processor_data['params']['testmode'] != "N") ? "https://test.sagepay.com/gateway/service/vspform-register.vsp" : "https://live.sagepay.com/gateway/service/vspform-register.vsp";

    $post["VPSProtocol"] = "2.23";
    $post["TxType"] = $processor_data["params"]["transaction_type"];
    $post["Vendor"] = htmlspecialchars($processor_data["params"]["vendor"]);

    // Form Cart products
    $strings = 0;
    if (is_array($cart['products'])) {
        $strings += count($cart['products']);
    }

    if (!empty($cart['products'])) {
        foreach ($cart['products'] as $v) {
            $_product = db_get_field("SELECT product FROM $db_tables[product_descriptions] WHERE product_id='$v[product_id]' AND lang_code='$cart_language'");
            $products_string .= ":".str_replace(":", " ", $_product).":".$v['amount'].":".fn_format_price($v['subtotal']/$v['amount']).":::".fn_format_price($v['subtotal']);
        }
    }
    if (!empty($cart['payment_surcharge'])) {
        $products_string .= ":Payment surcharge:---:---:---:---:".fn_format_price($cart['payment_surcharge']);
        $strings ++;
    }
    if (!empty($cart['shipping_cost'])) {
        $products_string .= ":Shipping cost:---:---:---:---:".fn_format_price($cart['shipping_cost']);
        $strings ++;
    }
    $post_encrypted .= "Basket=".$strings.$products_string;

    $post["Crypt"] = base64_encode(simpleXor($post_encrypted, $processor_data["params"]["password"]));
    $post["Crypt"] = htmlspecialchars($post["Crypt"]);

    $msg = fn_get_lang_var('text_cc_processor_connection');
    $msg = str_replace('[processor]', 'Protx Server', $msg);

echo <<<EOT
<html>
<body onLoad="document.process.submit();">
<form action="{$post_address}" method="POST" name="process">
<INPUT type=hidden name="VPSProtocol" value="{$post['VPSProtocol']}">
<INPUT type=hidden name="Vendor" value="{$post['Vendor']}">
<INPUT type=hidden name="TxType" value="{$post['TxType']}">
<INPUT type=hidden name="Crypt" value="{$post['Crypt']}">
<p>
<div align=center>{$msg}</div>
</p>
</body>
</html>
EOT;
}

exit;

//
// ---------------- Additional functions ------------
//
function simpleXor($InString, $Key) {
$KeyList = array();
$output = "";

for($i = 0; $i < strlen($Key); $i++){
    $KeyList[$i] = ord(substr($Key, $i, 1));
}
for($i = 0; $i < strlen($InString); $i++) {
    $output.= chr(ord(substr($InString, $i, 1)) ^ ($KeyList[$i % strlen($Key)]));
}

return $output;
}

function base64Decode($scrambled) {
// Initialise output variable
$output = "";
// Fix plus to space conversion issue
$scrambled = str_replace(" ","+",$scrambled);
// Do encoding
$output = base64_decode($scrambled);
// Return the result
return $output;
}
?>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could try dropping the following functions into the script, then swapping out simpleXor for encryptAes. Make sure that you also add an '@' symbol as the first character of the crypt string (and strip it off when decoding the response from Sage Pay).

function addPKCS5Padding($input)
{
     $blockSize = 16;
     $padd = "";
     $length = $blockSize - (strlen($input) % $blockSize);
     for ($i = 1; $i <= $length; $i++)
{
     $padd .= chr($length);
}
     return $input . $padd;
}

function removePKCS5Padding($input)
{
    $blockSize = 16;
    $padChar = ord($input[strlen($input) - 1]);
    $unpadded = substr($input, 0, (-1) * $padChar);
    return $unpadded;
}


function encryptAes($string, $key)
{
    $string = addPKCS5Padding($string);
    $crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $key);
    return  strtoupper(bin2hex($crypt));
}


function decryptAes($strIn, $password)
{
    $strInitVector = $password;
    $strIn = pack('H*', $hex);
    $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $password, $strIn, MCRYPT_MODE_CBC,$strInitVector);
    return removePKCS5Padding($string);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...