为什么使用相同的密钥和数据时,PHP 和 Python 中的 AES-256-CBC 结果不同?

问题描述 投票:0回答:1

我正在尝试使用 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=

我已验证以下内容:

  • 两种语言的密钥和IV都是使用SHA-256以相同的方式生成的。
  • 我正在使用 CBC 模式并在两种语言中应用 PKCS7 填充。
  • 两个结果都是 Base64 编码的。

尽管采取了这些步骤,结果仍然不同。我不确定为什么会发生这种情况。

python php encryption aes pycryptodome
1个回答
0
投票

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 代码相同的结果。

© www.soinside.com 2019 - 2024. All rights reserved.