Python代码:
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64
def encrypt_string(input_string, key_base64, str_iv):
try:
key = key_base64.encode('utf-8')
if str_iv:
iv = base64.b64decode(str_iv)
else:
iv = get_random_bytes(16)
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_data = pad(input_string.encode(), AES.block_size)
cipher_data = cipher.encrypt(padded_data)
combined_data = iv + cipher_data
return base64.b64encode(combined_data).decode()
except Exception as e:
print(e)
if __name__ == "__main__":
key = "1bd393e7a457f9023d9ba95fffb5a2e1"
iv = "1oTOhV9xGyu1mppmWZWa5w=="
input_string = "AAAAAAA"
encrypted_data = encrypt_string(input_string, key, iv)
print("Encrypted string:", encrypted_data)`
输出: 加密字符串:1oTOhV9xGyu1mppmWZWa5+kzveiTRzRH+gRVHx+7Ad0=
PHP代码:
<?php
function encrypt_string($input_string, $key_base64, $str_iv) {
try {
$key = base64_decode($key_base64);
if ($str_iv) {
$iv = base64_decode($str_iv);
} else {
$iv = openssl_random_pseudo_bytes(16);
}
$ciphertext = openssl_encrypt($input_string, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
$combined_data = $iv . $ciphertext;
return base64_encode($combined_data);
} catch (Exception $e) {
echo $e->getMessage();
}
}
$key = "1bd393e7a457f9023d9ba95fffb5a2e1";
$iv = "1oTOhV9xGyu1mppmWZWa5w==";
$input_string = "AAAAAAA";
$encrypted_data = encrypt_string($input_string, $key, $iv);
echo "Encrypted string: " . $encrypted_data . "\n";
?>
输出: 加密字符串:1oTOhV9xGyu1mppmWZWa53Nc8rxWTultBWLvWitUICQ=
请问有谁知道如何使这两个代码的输出相同?
问题出在您的 PHP 代码中。
openssl_encrypt
函数采用 passpharse
参数:
如果密码短于预期,则会用 NUL 字符默默填充;如果密码比预期长,它会被静默截断。
对于 AES 256,这应该是 32 个字符。您的
$key
变量正在用 \null
字节填充。
区别在于每个函数的第一行:
# this just converts the key from a string to bytes
key = key_base64.encode('utf-8')
//this base64 decodes the key.
$key = base64_decode($key_base64);
要使 Python 代码与 PHP 代码相同,您需要执行以下操作:
key = base64.b64decode(key)
但是,稍后在 Python 代码中这会失败,因为密钥的长度只有 24,而 Python 不会默默地填充密钥。
我的建议是使用密钥的哈希值作为密码。以下是 Python 和 PHP 中的示例。为了简单起见,我删除了异常处理。
from cryptography.hazmat.primitives.ciphers import Cipher, modes
from cryptography.hazmat.primitives.ciphers.algorithms import AES256
from cryptography.hazmat.primitives.padding import PKCS7
import hashlib
import base64
def encrypt_string(input_string: str, key: bytes, iv: bytes):
key_hash = hashlib.sha256(key).digest()[:32]
cipher = Cipher(AES256(key_hash), modes.CBC(iv))
pad = PKCS7(AES256.block_size).padder()
encryptor = cipher.encryptor()
cipher_data = encryptor.update(
pad.update(input_string.encode('utf-8'))
+ pad.finalize()
)
combined_data = iv + cipher_data
return base64.b64encode(combined_data)
if __name__ == '__main__':
key = b'password'
iv = b'aaaabbbbccccdddd'
input_string = "abcdefghijklmnopqrstuvwxyz"
encrypted_data = encrypt_string(input_string, key, iv)
print("Encrypted string:", encrypted_data)
# prints:
# Encrypted string: b'YWFhYWJiYmJjY2NjZGRkZALrlaYfFmHrO6FOv64BdVueK/yYNjjgtdQx+A0eR9iv'
以及 PHP 代码:
<?php
function encrypt_string($input_string, $key, $iv) {
$key_hash = substr(hash('sha256', $key, true), 0, 32);
$ciphertext = openssl_encrypt($input_string, "aes-256-cbc", $key_hash, OPENSSL_RAW_DATA, $iv);
$combined_data = $iv . $ciphertext;
return base64_encode($combined_data);
}
$key = 'password';
$iv = "aaaabbbbccccdddd";
$input_string = "abcdefghijklmnopqrstuvwxyz";
$encrypted_data = encrypt_string($input_string, $key, $iv);
echo "Encrypted string: " . $encrypted_data . "\n";
?>