title: Sagepay error 5068: encryption method not supported (Upgrade from 2.22 to 3.00)
body: <p>I've already looked through answers to other questions on the Sagepay protocol upgrade from 2.22 to 3.00, including the answer on my own previous question.</p>
  
  <p>I am trying to update the encryption method from Xor to AES so the 3.00 protocol will work but have thus far got stuck on the Sagepay error 5068: the encryption method is not supported by this protocol. My company's three websites that need to be updated are based on the JShop e-commerce platform which is very outdated and no longer offers support.</p>
  
  <p>I have implemented two solutions given as answers, one of which is taken from the Sagepay php documents available on their website but am still receiving this error.</p>
  
  <p>I'd appreciate some input into where I am going wrong.</p>
  
  <p>Have contacted Sagepay but they're not much help and have previously directed me here or to their partners page.</p>
  
  <p>Protx (Sagepay) file:</p>
  
  <pre><code>    &lt;?php
  
  
      function startProcessor($orderNumber) {
  
          global $dbA,$orderArray,$jssStoreWebDirHTTP,$jssStoreWebDirHTTPS,$cartMain;
  
  
  
          $callBack = "$jssStoreWebDirHTTPS"."gateways/response/protx.php";
  
  
  
          $cDetails = returnCurrencyDetails($orderArray["currencyID"]);
  
  
  
          $gatewayOptions = retrieveGatewayOptions("PROTX");
  
          switch ($gatewayOptions["testMode"]) {
  
              case "S":
  
                  $myAction = "https://test.sagepay.com/Simulator/VSPFormGateway.asp";
  
                  break;
  
              case "Y":
  
                  $myAction = "https://test.sagepay.com/gateway/service/vspform-register.vsp";
  
                  break;
  
              case "N":
  
                  $myAction = "https://live.sagepay.com/gateway/service/vspform-register.vsp";
  
                  break;
  
          }
  
          $myVendor = $gatewayOptions["vendor"];
  
          $myEncryptionPassword = $gatewayOptions["encryptionPassword"];
  
  
  
          $billingAddress  = $orderArray["address1"]."\n";
  
          if ($orderArray["address2"] != "") {
  
              $billingAddress .= $orderArray["address2"]."\n";
  
          }
  
          $billingAddress .= $orderArray["town"]."\n";
  
          $billingAddress .= $orderArray["county"]."\n";
  
          $billingAddress .= $orderArray["country"];
  
  
  
          $deliveryAddress  = $orderArray["deliveryAddress1"]."\n";
  
          if ($orderArray["deliveryAddress2"] != "") {
  
              $deliveryAddress .= $orderArray["deliveryAddress2"]."\n";
  
          }
  
          $deliveryAddress .= $orderArray["deliveryTown"]."\n";
  
          $deliveryAddress .= $orderArray["deliveryCounty"]."\n";
  
          $deliveryAddress .= $orderArray["deliveryCountry"];
  
  
  
  
  
          $crypt = "VendorTxCode=$orderNumber";
  
          $crypt .= "&amp;Amount=".number_format($orderArray["orderTotal"],$cDetails["decimals"],'.','');
  
          $crypt .= "&amp;Currency=".@$cDetails["code"];
  
          $crypt .= "&amp;Description=".$gatewayOptions["description"];
  
          $crypt .= "&amp;SuccessURL=$callBack?xOid=$orderNumber&amp;xRn=".$orderArray["randID"];
  
          $crypt .= "&amp;FailureURL=$callBack?xOid=$orderNumber&amp;xRn=".$orderArray["randID"];
  
          $crypt .= "&amp;BillingSurname=".$orderArray["surname"];
  
          $crypt .= "&amp;BillingFirstnames=".$orderArray["forename"];
  
          $crypt .= "&amp;BillingAddress1=".$orderArray["address1"];
  
          $crypt .= "&amp;BillingCity=".$orderArray["town"];
  
          $crypt .= "&amp;BillingPostCode=".preg_replace("/[^\s\-a-zA-Z0-9]/", "", $orderArray["postcode"]);
  
          $crypt .= "&amp;BillingCountry=".$orderArray["country"];
  
          $crypt .= "&amp;DeliverySurname=".$orderArray["surname"];
  
          $crypt .= "&amp;DeliveryFirstnames=".$orderArray["forename"];
  
      if ($orderArray["deliveryPostcode"] != "") {
          $crypt .= "&amp;DeliveryAddress1=".$orderArray["deliveryAddress1"];
  
          $crypt .= "&amp;DeliveryCity=".$orderArray["deliveryTown"];
  
          $crypt .= "&amp;DeliveryPostCode=".preg_replace("/[^\s\-a-zA-Z0-9]/", "", $orderArray["deliveryPostcode"]);
  
          $crypt .= "&amp;DeliveryCountry=".$orderArray["deliveryCountry"]; }
  
      else {
          $crypt .= "&amp;DeliveryAddress1=".$orderArray["address1"];
  
          $crypt .= "&amp;DeliveryCity=".$orderArray["town"];
  
          $crypt .= "&amp;DeliveryPostCode=".preg_replace("/[^\s\-a-zA-Z0-9]/", "", $orderArray["postcode"]);
  
          $crypt .= "&amp;DeliveryCountry=".$orderArray["country"]; }
  
          $crypt .= "&amp;BillingPhone=".preg_replace("/[^\sa-zA-Z0-9]/", "", $orderArray["telephone"]);
  
          if ($gatewayOptions["sendEmail"] == 1) {
          $crypt .= "&amp;CustomerEmail=".$orderArray["email"]; }
  
  
          $crypt .= "&amp;VendorEmail=".$gatewayOptions["vendorEmail"];
  
          $crypt .= "&amp;ApplyAVSCV2=".$gatewayOptions["cvvCheck"];
          $crypt .= "&amp;Apply3dSecure=".$gatewayOptions["3DSecure"];
  
  
  
  
          $crypt = base64_encode(encryptAes($crypt, $myEncryptionPassword));
  
          $tpl = createTSysObject(templatesCreatePath($cartMain["templateSet"]),"gatewaytransfer.html",$requiredVars,0);
  
  
  
          $gArray["method"] = "POST";
  
          $gArray["action"] = $myAction;
  
          $gArray["fields"][] = array("name"=&gt;"VPSProtocol","value"=&gt;"3.00");
  
          $gArray["fields"][] = array("name"=&gt;"Vendor","value"=&gt;$myVendor);
  
          $gArray["fields"][] = array("name"=&gt;"TxType","value"=&gt;$gatewayOptions["txType"]);
  
          $gArray["fields"][] = array("name"=&gt;"Crypt","value"=&gt;$crypt);
  
  
  
          $mArray = $gArray;
  
  
  
          $gArray["process"] = "document.automaticForm.submit();";
  
  
  
          $tpl-&gt;addVariable("shop",templateVarsShopRetrieve());
  
          $tpl-&gt;addVariable("labels",templateVarsLabelsRetrieve());
  
  
  
          $tpl-&gt;addVariable("automaticForm",$gArray);
  
          $tpl-&gt;addVariable("manualForm",$mArray);
  
          $tpl-&gt;showPage();
  
      }
  
      function addPKCS5Padding($input)
      {
           $blockSize = 16;
           $padd = "";
           $length = $blockSize - (strlen($input) % $blockSize);
           for ($i = 1; $i &lt;= $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, $myEncryptionPassword)
      {
  
      #Sagepay specific - remove the '@'
      $strIn = substr($strIn,1);
  
          $strInitVector = $myEncryptionPassword;
          $strIn = pack('H*', $hex);
          $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $myEncryptionPassword, $strIn, MCRYPT_MODE_CBC,$strInitVector);
          return removePKCS5Padding($string);
      }
  
  ?&gt;
  </code></pre>
  
  <p>Response file:</p>
  
  <pre><code> &lt;?php
  
      define("IN_JSHOP", TRUE);
  
      include("../../static/config.php");
  
      include("../../routines/dbAccess_".$databaseType.".php");
  
      include("../../routines/tSys.php");
  
      include("../../routines/general.php");
  
      include("../../routines/stockControl.php");
  
      include("../../routines/emailOutput.php");
  
      require_once 'SagepayUtil.php';
  
  
  
      dbConnect($dbA);
  
  
  
      $orderID = makeSafe(getFORM("xOid"));
  
      $newOrderID = $orderID;
  
      $randID = makeSafe(getFORM("xRn"));
  
      $crypt = makeSafe(getFORM("crypt"));
  
  
  
      $gatewayOptions = retrieveGatewayOptions("PROTX");
  
  
  
      $orderID = makeInteger($orderID) - retrieveOption("orderNumberOffset");
  
  
  
      $result =  $dbA-&gt;query("select * from $tableOrdersHeaders where orderID=$orderID and randID='$randID'");
  
      if ($dbA-&gt;count($result) == 0 || $crypt=="") {
  
          doRedirect_JavaScript($jssStoreWebDirHTTP."index.php");
  
          exit;
  
      }
  
      $orderArray = $dbA-&gt;fetch($result);
  
      $ccResult = $dbA-&gt;query("select * from $tablePaymentOptions where paymentID=".$orderArray["paymentID"]);
  
      $poRecord = $dbA-&gt;fetch($ccResult);
  
      $paidStatus = $poRecord["statusID"];
  
  
  
      $crypt = str_replace(" ","+",$crypt);
  
      //$crypt = protx_simpleXor(base64_decode($crypt),$gatewayOptions["encryptionPassword"]);
  
      $crypt = decryptAes(base64_decode($crypt), $gatewayOptions["encryptionPassword"]);
  
  
  
      $nameValues = explode("&amp;",$crypt);
  
      $resultCode = "";
  
      for ($f = 0; $f &lt; count($nameValues); $f++) {
  
          $thisCode = explode("=",$nameValues[$f]);
  
          $resultCode[$thisCode[0]] = $thisCode[1];
  
      }
  
  
  
      if ($resultCode["VendorTxCode"] != $newOrderID) {
  
          doRedirect_JavaScript($jssStoreWebDirHTTP."index.php");
  
          exit;
  
      }
  
  
  
      $authResponse = "&amp;Status Result=".$resultCode["Status"]."&amp;AVS/CV2 Check=".@$resultCode["AVSCV2"]."&amp;Address Result=".@$resultCode["AddressResult"]."&amp;Postcode Result=".@$resultCode["PostCodeResult"]."&amp;CV2 Result=".@$resultCode["CV2Result"]."&amp;3d Secure Status=".@$resultCode["3DSecureStatus"];
  
  
  
      $randID = $orderArray["randID"];
  
      if ($orderArray["status"] != $paidStatus) {
  
              $dt=date("YmdHis",createOffsetTime());
  
              switch ($resultCode["Status"]) {
  
                  case "OK":
  
                  case "AUTHENTICATED":
  
                  case "REGISTERED":
  
                      $authResponse="Gateway=Sage Pay&amp;Authorisation Code=".$resultCode["TxAuthNo"]."&amp;Sage Pay Transaction ID=".$resultCode["VPSTxId"]."&amp;Status=Payment Confirmed".$authResponse;
  
                      $dbA-&gt;query("update $tableOrdersHeaders set status=$paidStatus, authInfo=\"$authResponse\", paymentDate=\"$dt\" where orderID=$orderID");
  
                      $orderArray["status"] = $paidStatus;
  
                      //ok, this is where we should do the stock control then.
  
                      include("process/paidProcessList.php");
  
                      doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&amp;xRn=$randID");
  
                      break;
  
                  case "REJECTED":
  
                      $authResponse="Gateway=Sage Pay&amp;Status=Payment Rejected Due To Rules".$authResponse;
  
                      $dbA-&gt;query("update $tableOrdersHeaders set status=3, authInfo=\"$authResponse\", paymentDate=\"$dt\" where orderID=$orderID");
  
                      include("process/failProcessList.php");
  
                      doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&amp;xRn=$randID");
  
                      break;
  
                  default:
  
                      if ($orderArray["status"] == 1) {
  
                          $authResponse="Gateway=Sage Pay&amp;Status=Payment Failed".$authResponse;
  
                          $dbA-&gt;query("update $tableOrdersHeaders set status=3, authInfo=\"$authResponse\", paymentDate=\"$dt\" where orderID=$orderID");
  
                          include("process/failProcessList.php");
  
                  }
  
                      doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&amp;xRn=$randID");
  
                      break;
  
              }
  
      } else {
  
              doRedirect_JavaScript($jssStoreWebDirHTTPS."process.php?xOid=$newOrderID&amp;xRn=$randID");
  
      }
  
  
  
      function addPKCS5Padding($input)
      {
           $blockSize = 16;
           $padd = "";
           $length = $blockSize - (strlen($input) % $blockSize);
           for ($i = 1; $i &lt;= $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, $myEncryptionPassword)
      {
  
      #Sagepay specific - remove the '@'
      $strIn = substr($strIn,1);
  
          $strInitVector = $myEncryptionPassword;
          $strIn = pack('H*', $hex);
          $string = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $myEncryptionPassword, $strIn, MCRYPT_MODE_CBC,$strInitVector);
          return removePKCS5Padding($string);
      }
  
  ?&gt;
  </code></pre>