Search code examples
phpencryptionaesopayo

AES/CBC/PKCS#5 Encryption Algorithm In PHP


Im attempting to integrate the SagePay payment gateway into a website using the 'Form Integration' method.

Basically the form integration method works by inserting a FORM in a webpage and POSTing information to SagePay's servers whenever the Submit button for the FORM is selected. Before the information can be sent to SagePay's servers it must be encrypted using the AES/CBC/PKCS#5 algorithm, before being Base 64 encoded.

I have a basic knowledge of encryption but I have no experience of using it in PHP. Can anyone please help me formulate the AES/CBC/PKCS#5 algorithm in PHP please?

Here's my efforts so far:

$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>";

Any help is much appreciated.


Solution

  • Yes, that's fine. (As soon as we have a PHP kit for v3.00 we'll display it on our website).

    Hope the below helps you to.

    Example:

    AES encryption with Base64 encoding AES encryption, CBC blocking with PKCS5 padding then HEX encoding

    //** 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));
    } 
    
    }