我正在尝试使用 AES-256-CBC 使用相同的密钥和 IV 来加密 PHP 和 Python 中的相同字符串。然而,两种语言的结果是不同的,即使我使用相同的加密方法和相同的数据。
在 PHP 中,我使用
openssl_encrypt
,而在 Python 中,我使用 pycryptodome
和 PKCS7 填充。下面是我正在使用的两个代码片段以及我得到的结果。
<?php
$plaintextstr = 'AAAAAAAAAAAAAAAA';
$encrypt_method = "AES-256-CBC";
$secret_key = "SSSSSSSSSSSS";
$secret_iv = "LLLLLLLLLLLL";
$key = substr(hash('sha256', $secret_key), 0, 32);
$iv = substr(hash('sha256', $secret_iv), 0, 16);
$encrypted_str = openssl_encrypt($plaintextstr, $encrypt_method, $key, 0, $iv);
echo $encrypted_str;
// result = uDMtRDB49A5t+UZ0IhDuKieH7Trr6GBG/ADWcZMxIuw=
?>
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from hashlib import sha256
import base64
# Input data
plaintextstr = 'AAAAAAAAAAAAAAAA'
secret_key = "SSSSSSSSSSSS"
secret_iv = "LLLLLLLLLLLL"
# Generate Key and IV using Sha256
key = sha256(secret_key.encode('utf-8')).digest()[:32]
iv = sha256(secret_iv.encode('utf-8')).digest()[:16]
# Ensure that the data is encoded in UTF-8 and apply Padding PKCS7
padded_data = pad(plaintextstr.encode('utf-8'), AES.block_size)
# Create AES encryption in CBC mode
cipher = AES.new(key, AES.MODE_CBC, iv)
# Encrypt the data
encrypted = cipher.encrypt(padded_data)
# Convert the result in basis64 (as in PHP)
encrypted_base64 = base64.b64encode(encrypted).decode('utf-8')
# Print the basis encrypted based64
print(encrypted_base64)
# result = V7zSp9KHPke9QuPbWoUNvjCHVJ7giluD9YaOnX9E57k=
我已验证以下内容:
尽管采取了这些步骤,结果仍然不同。我不确定为什么会发生这种情况。
php
hash
函数返回字节的十六进制表示形式,因此用 substr 删除其中的 16 个字符会得到 IV 的“20139ebeee312271”(与 key 的结果类似)。这些不是真正的字节,它们是 [0-9a-f]
范围内的字符。这不是你想要做的。
Python
sha256
函数返回字节字符串,而不是十六进制表示形式。删除其中的 16 个字符会从哈希中得到 16 个真实字节。这可能就是您打算做的。
结果不同,因为您使用不同的密钥和初始化向量进行加密。
将 PHP 代码更改为:
<?php
$plaintextstr = 'AAAAAAAAAAAAAAAA';
$encrypt_method = "AES-256-CBC";
$secret_key = "SSSSSSSSSSSS";
$secret_iv = "LLLLLLLLLLLL";
$key = substr(hex2bin(hash('sha256', $secret_key)), 0, 32);
$iv = substr(hex2bin(hash('sha256', $secret_iv)), 0, 16);
$encrypted_str = openssl_encrypt($plaintextstr, $encrypt_method, $key, 0, $iv);
echo $encrypted_str;
产生与 python 代码相同的结果。