Convert openssl AES in Php to Python AES

大兔子大兔子 提交于 2021-02-10 06:14:45

问题


I have a php file which is as follow:

$encryption_encoded_key = 'c7e1wJFz+PBwQix80D1MbIwwOmOceZOzFGoidzDkF5g=';

function my_encrypt($data, $key) {
    $encryption_key = base64_decode($key);
    $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cfb'));

    $encrypted = openssl_encrypt($data, 'aes-256-cfb', $encryption_key, 1, $iv);

    // The $iv is just as important as the key for decrypting, so save it with encrypted data using a unique separator (::)
    return base64_encode($encrypted . '::' . $iv);
}

function my_decrypt($data, $key) {
    // Remove the base64 encoding from key
    $encryption_key = base64_decode($key);

    // To decrypt, split the encrypted data from IV - unique separator used was "::"
    list($encrypted_data, $iv) = explode('::', base64_decode($data), 2);

    return openssl_decrypt($encrypted_data, 'aes-256-cfb', $encryption_key, 1, $iv);
}

$data = 'USER_ID||NAME||EMAIL||MOBILE';
$data_encrypted = my_encrypt($data, $encryption_encoded_key);
echo $data_encrypted;
$data_decrypted = my_decrypt($data_encrypted, $encryption_encoded_key);
echo "Decrypted string: ". $data_decrypted;

This works fine, and is able to encrypt/decrypt with the encryption key, now i also have a python file:

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

encryption_encoded_key = 'c7e1wJFz+PBwQix80D1MbIwwOmOceZOzFGoidzDkF5g='

def my_encrypt(data, key):
    #Remove the base64 encoding from key
    encryption_key = base64.b64decode(key)
    #Generate an initialization vector
    bs = AES.block_size
    iv = Random.new().read(bs)

    cipher = AES.new(encryption_key, AES.MODE_CFB, iv)
    #Encrypt the data using AES 256 encryption in CBC mode using our encryption key and initialization vector.
    encrypted = cipher.encrypt(data)

    #The iv is just as important as the key for decrypting, so save it with encrypted data using a unique separator (::)
    return base64.b64encode(encrypted + '::' + iv)


def my_decrypt(data, key):
    #Remove the base64 encoding from key
    encryption_key = base64.b64decode(key)

    #To decrypt, split the encrypted data from IV - unique separator used was "::"
    encrypted_data, iv = base64.b64decode(data).split('::')

    cipher = AES.new(encryption_key, AES.MODE_CFB, iv)

    return cipher.decrypt(encrypted_data)

data = 'USER_ID||NAME||EMAIL||MOBILE'

print "Actual string: %s" %(data)
data_encrypted = my_encrypt(data, encryption_encoded_key)
print data_encrypted

data_decrypted = my_decrypt(data_encrypted, encryption_encoded_key)
print "Decrypted string: %s" %(data_decrypted)

This also works fine when i try to use this from python, it is able to encrypt/decrypt input string, I want to encrypt using php file and decrypt the output in python, both should use AES 256 Encryption using CFB mode, what am i doing wrong ?


回答1:


To use CFB mode you need to specify a segment size for it. OpenSSL has aes-256-cfb (which is 128 bit), aes-256-cfb1 (i.e. 1-bit) and aes-256-cfb8 (8 bit) (and similar modes for AES-128 and 192). So you are using 128 bit cfb in your php code.

The Python library accepts a segment_size argument to AES.new, but the default is 8, so you are using different modes in the two versions.

To get the Python code to decrypt the output of the PHP code, add a segment size of 128 to the cipher object:

cipher = AES.new(encryption_key, AES.MODE_CFB, iv, segment_size=128)

(N.B. this is using the newer PyCryptodome fork of PyCrypto. PyCrypto has a bug here and won’t work.)

Alternatively, you can get the PHP code to use CFB-8 by setting the cipher (don’t change both, obviously):

$encrypted = openssl_encrypt($data, 'aes-256-cfb8', $encryption_key, 1, $iv);


来源:https://stackoverflow.com/questions/46346371/convert-openssl-aes-in-php-to-python-aes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!