简体   繁体   中英

Python Encrypt AES MODE_CBC with PKCS#5 Padding

I'm trying to do a form integration with Sagepay, using Python and Flask.

Part of the process is to do the following:

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. Prependthe'@'signtothebeginningoftheencodedresult.*

I'm completely stuck with trying to do this - I've build the url as per this part:

VendorTxCode=TxCode-1310917599-223087284&Amount=36.95&Currency=GBP&Description=description&CustomerName=Fname Surname&CustomerEMail=customer@example.com&BillingSurname=Surname&BillingFirstnames=Fname&BillingAddress1=BillAddress Line 1&BillingCity=BillCity&BillingPostCode=W1A 1BL&BillingCountry=GB&BillingPhone=447933000000&DeliveryFirstnames=Fname&DeliverySurname=Surname&DeliveryAddress1=BillAddress Line 1&DeliveryCity=BillCity&DeliveryPostCode=W1A 1BL&DeliveryCountry=GB&DeliveryPhone=447933000000&SuccessURL=https://example.com/success&FailureURL=https://example.com/failur e

but now need to encrypt it using AES MODE_CBC with PKCS#5 padding.

The example code in PHP is:

    static public function encryptAes($string, $key)
{
    // AES encryption, CBC blocking with PKCS5 padding then HEX encoding.
    // Add PKCS5 padding to the text to be encypted.
    $string = self::addPKCS5Padding($string);

    // Perform encryption with PHP's MCRYPT module.
    $crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_CBC, $key);

    // Perform hex encoding and return.
    return "@" . strtoupper(bin2hex($crypt));
}

I've tried the following:

from Crypto.Cipher import AES
mycrptobj = AES.new('55a51621a6648525', AES.MODE_CBC, os.urandom(16))
ciphertext = mycryptobj.encrypt('somewords')

But get the input strings must be a multiple of 16 in length.

So.

I've tried following the other stack overflow questions on this but:

  1. I don't know what the IV is! am I correct in generating a random id? re-reading shows to use the key are the INITIALISATION VECTOR which I assume is the IV

  2. Is this the correct process?

For anyone interested I've managed to get it working and put the resulting class on Github. https://github.com/Bobspadger/sagepay/blob/master/sagepay.py

This will encrypt and decrypt to Sagepays current v3.0 protocol specifications.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM