Correctly migrate from Python 2 md5 library to Python 3 hashlib

Question:

I’m trying to integrate a 3rd party payment gateway (CCAvenue) in Django 1.11, Python 3.5.2

The reference code provided by the 3rd party uses the deprecated library md5 to encrypt texts.

from Crypto.Cipher import AES
import md5

def pad(data):
    length = 16 - (len(data) % 16)
    data += chr(length)*length
    return data

def encrypt(plainText,workingKey):
    iv = 'x00x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0f'
    plainText = pad(plainText)
    encDigest = md5.new ()
    encDigest.update(workingKey)
    enc_cipher = AES.new(encDigest.digest(), AES.MODE_CBC, iv)
    encryptedText = enc_cipher.encrypt(plainText).encode('hex')
    return encryptedText

How do I make the above encrypt() method Python 3 compatible using the hashlib library of Python 3? Can you post the whole method?

Asked By: Rajeev Ravindran

||

Answers:

WARNING: Don’t use crypto or pycrypto anymore! read more

Here’s a Python 3 compatible way of doing the same:

from binascii import hexlify, unhexlify
from Crypto.Cipher import AES
from hashlib import md5

from django.utils.encoding import force_bytes

iv = 'x00x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0f'
# for python 3.9 & pycryptodome, this need to be byte
iv = b'x00x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0f'

BS = 16


def _pad(data):
    return data + (BS - len(data) % BS) * chr(BS - len(data) % BS)


def _unpad(data):
    return data[0:-ord(data[-1])]


def encrypt(plain_text, working_key):
    plain_text = _pad(plain_text)
    enc_cipher = AES.new(md5(force_bytes(working_key)).digest(), AES.MODE_CBC, _iv)
    return hexlify(enc_cipher.encrypt(plain_text)).decode('utf-8')


def decrypt(cipher_text, working_key):
    encrypted_text = unhexlify(cipher_text)
    dec_cipher = AES.new(md5(force_bytes(working_key)).digest(), AES.MODE_CBC, _iv)
    return _unpad(dec_cipher.decrypt(encrypted_text).decode('utf-8'))
Answered By: Ashwini Chaudhary

Works perfectly for python3.8 and Django 3.2 pycryptodome==3.17

 from Crypto.Cipher import AES
 import hashlib
 from binascii import hexlify, unhexlify

def pad(data):
    length = 16 - (len(data) % 16)
    data += chr(length)*length
    return data

def unpad(data):
    return data[0:-ord(data[-1])]

def encrypt(plainText, workingKey):
    iv =b'x00x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0f'
    plainText = pad(plainText)
    bytearrayWorkingKey = bytearray()
    bytearrayWorkingKey.extend(map(ord, workingKey))
    enc_cipher = AES.new(hashlib.md5(bytearrayWorkingKey).digest(), AES.MODE_CBC, iv)
    return hexlify(enc_cipher.encrypt(plainText.encode('utf-8'))).decode('utf-8')

def decrypt(cipherText, workingKey):
    iv = b'x00x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0f'
    encryptedText = unhexlify(cipherText)
    bytearrayWorkingKey = bytearray()
    bytearrayWorkingKey.extend(map(ord, workingKey))
    decCipher = AES.new(hashlib.md5(bytearrayWorkingKey).digest(), AES.MODE_CBC, iv)
    return unpad(decCipher.decrypt(encryptedText).decode('utf-8'))`
Answered By: vinod kumar
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.