2

I am just wondering is it possible to convert PHP encryption function to Python? I am using PHP function to encrypt USER ID and store it in Database and now I need to decrypt USER ID in Python, I using this PHP function:

function decrypt($id) {
       $cryptKey  = '123';
       $decoded    = rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, md5( $cryptKey ),         base64_decode( $id ), MCRYPT_MODE_CBC, md5( md5( $cryptKey ) ) ), "\0");
       return( $decoded );
    }
1

1 Answer 1

7

Here is your function 'translated' to python

from Crypto.Cipher import AES
from hashlib import md5

def decrypt(id): 
    cryptKey  = '123'
    cipher = AES.new(key=md5(cryptKey).hexdigest(), mode=AES.MODE_CBC, IV=md5(md5(cryptKey).hexdigest()).hexdigest()[:16])
    decoded = cipher.decrypt(id.decode('base64')).rstrip('\0')
    return decoded

A fiew suggestions
1. Use a random iv
2. Use a more complex key
3. Don't hardcode the key
4. Use openssl_decrypt , mcrypt_decrypt is deprecated

Note
This will not work with MCRYPT_RIJNDAEL_256 because it uses 32 byte blocks .
But you could use MCRYPT_RIJNDAEL_128 or openssl

Here is an example with openssl AES CBC in PHP :

function encrypt($data, $key) {
    $method = "aes-" . strlen($key) * 8 . "-cbc";
    $iv = openssl_random_pseudo_bytes(16);
    $encoded = base64_encode($iv . openssl_encrypt($data, $method, $key, TRUE, $iv));
    return $encoded;
}

function decrypt($data, $key) {
    $method = "aes-" . strlen($key) * 8 . "-cbc";
    $iv = substr(base64_decode($data), 0, 16);
    $decoded = openssl_decrypt(substr(base64_decode($data), 16), $method, $key, TRUE, $iv);
    return $decoded;
}

Python code :

from Crypto.Cipher import AES
from Crypto import Random
import base64

def encrypt(data, key): 
    pkcs7pad = lambda data: data + chr(16-(len(data)%16)).encode() * (16-(len(data)%16))
    iv = Random.new().read(16)
    cipher = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
    encoded = base64.b64encode(iv + cipher.encrypt(pkcs7pad(data)))
    return encoded

def decrypt(data, key): 
    pkcs7unpad = lambda data: data[:-ord(data[-1:])]
    cipher = AES.new(key=key, mode=AES.MODE_CBC, IV=base64.b64decode(data)[:16])
    decoded = cipher.decrypt(base64.b64decode(data)[16:])
    return pkcs7unpad(decoded)

With the above functions you can encrypt in PHP - decrypt in python , and vice versa
Assuming that the key has a valid size (16, 24 or 32 bytes)

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, you have saved my day!:)
Yes, I have tried it I am receiving error: "binascii.Error: Incorrect padding" my encoded PHP id: "VjceE1sAhxf2kUJYJX5q1BruIco2ne9SBAjzmbgjfno%3D" as I understand something is not right with my encoded ID string I am looking for a solution right now
I receive same error:/ could it be there is a mistake in decode function?
Error: 'output = base64.decodestring(input) File "/usr/local/lib/python2.7/base64.py", line 328, in decodestring return binascii.a2b_base64(s) binascii.Error: Incorrect padding'
I could make it work with RIJNDAEL 128 and openssl_decrypt ( 128 and 256 ) , but not with RIJNDAEL 256
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.