SagePay V3 Form Integration using CFML - AES Encryption

417 views Asked by At

I've got through the entire FORM integration successfully except for the encryption.

Version 3 requires AES encryption and I don't understand how to implement this stage.

Previously, the CFML script constructed the crypt field at the end using this:

//** call to include file to encrypt
crypt = base64Encode (SimpleXor(stuff,EncryptionPassword));

This called the functions file which did the actual work.

The help I need is in creating a new script in the function.cfm file and also what the call should be.

Can anyone help, please?

Cheers

Here's a snippet of the code:

<cfscript>

ThisVendorTxCode = "#sfo_id#";

ThisVendorName = "pivotell";

stuff = "VendorTxCode=" & ThisVendorTxCode & "&";

stuff = stuff & "VendorName=" & ThisVendorName & "&";

</cfscript>

<cfset encryptionKey = generateSecretKey( "AES" ) />

//** call to include file to encrypt

<cfset crypt = encrypt(stuff,encryptionKey,"AES","hex") />

<cfoutput>

<form action="https://test.sagepay.com/gateway/service/vspform-register.vsp" method="post" id="form1" name="form1">

<input type="hidden" name="VPSProtocol" value="3.00">

<input type="hidden" name="TxType" value="PAYMENT">

<input type="hidden" name="Crypt" value="#crypt#">

</form>

</cfoutput>

I've truncated the full thing for simplicity.

1

There are 1 answers

2
Akos Fortagh On

It took me 3 days and 3 nights to figure this out. Please read page 37 of the Sage Pay Form Integration and Protocol Guidelines 3.00.

A1.1 The Crypt Field

  1. The Crypt field should contain all the other transaction information in plain text as Name=Value fields separated by ‘&’ characters. Ensure that all mandatory fields are present and that there are no spaces after the ‘&’ character.

  2. This string should then be encrypted using AES (block size 128-bit) in CBC mode with PKCS#5 padding using the provided password as both the key and initialisation vector and encode the result in hex (making sure the letters are in upper case).

  3. Prepend the ‘@’ sign to the beginning of the encoded result.

Together with the last answer on this post. It should sort it.

... Since your password string is not base64 encoded, the resulting key length is too small, ie (12) instead of (16) bytes. ...The solution is to base64 encode it first... Also, the iv parameter should be binary

  <cfset keyIVBytes = charsetDecode(yourKeyString, "utf-8")>
  <cfset base64Key = binaryEncode(keyIVBytes, "base64")>

  <cfset result = encrypt(plainString, base64Key,"AES/CBC/PKCS5Padding", "hex", keyIVBytes)>