将 PHP 中的 openssl AES 转换为 Python AES

2024-05-23

我有一个 php 文件,如下所示:

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

这工作正常,并且能够使用加密密钥加密/解密,现在我还有一个 python 文件:

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)

当我尝试从 python 使用它时,这也工作得很好,它能够加密/解密输入字符串, 我想使用 php 文件加密并解密 python 中的输出,两者都应该使用 CFB 模式使用 AES 256 加密,我做错了什么?


To use CFB mode https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_.28CFB.29你需要指定一个段大小为了它。 OpenSSL 有aes-256-cfb(这是128位),aes-256-cfb1(即 1 位)和aes-256-cfb8(8 位)(以及 AES-128 和 192 的类似模式)。所以您在 php 代码中使用 128 位 cfb。

Python 库接受segment_size论证AES.new,但默认是8,因此您在两个版本中使用不同的模式。

要让 Python 代码解密 PHP 代码的输出,请将大小为 128 的段添加到密码对象:

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

(注意,这是使用较新的PyCryptodome 叉子 https://github.com/Legrandin/pycryptodomePyCrypto 的。 PyCrypto 这里有一个错误,无法工作。)

或者,您可以通过设置密码来获取使用 CFB-8 的 PHP 代码(显然,不要同时更改两者):

$encrypted = openssl_encrypt($data, 'aes-256-cfb8', $encryption_key, 1, $iv);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 PHP 中的 openssl AES 转换为 Python AES 的相关文章

随机推荐