AES-256-CBC 加密在 Python 和 PHP 中返回不同的结果

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

Python代码:

import hashlib
import json
import base64
import requests
from Crypto.Cipher import AES


class Adauth:
    def __init__(self):
        self.secret_key = "SSSSSSSSSSSS"
        self.secret_iv = "LLLLLLLLLLLL"
        self.hashed_key = hashlib.sha256(self.secret_key.encode()).hexdigest()[:32]
        self.iv = hashlib.sha256(self.secret_iv.encode()).hexdigest()[:16]

    def encrypt_data(self,data):
        cipher = AES.new(self.hashed_key.encode("utf8"), AES.MODE_CBC, self.iv.encode("utf8"))
        encrypted = cipher.encrypt(data.encode("utf8"))
        return  base64.b64encode(encrypted).decode()


ad = Adauth()
data = "AAAAAAAAAAAAAAAA" #16 char
print ("Actual string: ", data)
s = ad.encrypt_data(data)
print("Encrypted string: ",s)

输出:

Actual string:  AAAAAAAAAAAAAAAA
Encrypted string:  osdKcm6x15VMHf/wHnA0uA==

PHP 代码:

<?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 "Actual string: ".$plaintextstr;
echo "Encrypted string: ".$encrypted_str;

输出:

Actual string: AAAAAAAAAAAAAAAA
Encrypted string: b3NkS2NtNngxNVZNSGYvd0huQTB1RG4vTVFmbmVhb1B2MTg4QUxpQUlGbz0=

我想要Python加密字符串与PHP加密字符串相同。 Python 代码有什么问题?

python php encryption aes
1个回答
-1
投票

实际上,问题在于

openssl_encrypt
将结果作为 Base64 编码的字符串返回,当您使用
base64_encode()
再次对其进行编码时,您会得到意外的结果。

注意:本来我误以为是Python代码中没有padding造成的。然而,正如评论中指出的那样,示例中的明文是 16 个字节,等于 AES 块大小,因此不需要任何填充。

解决方案

  • 不要对
    openssl_encrypt
    返回的值进行 Base64 编码,或者传递
    OPENSSL_RAW_DATA
    选项而不是零。
  • (可选)填充 Python 代码中的数据。如果数据是
    AES.block_size
    的倍数,则不需要。但是,在此处进行填充可能不会有什么坏处,只是为了确保明文大小发生变化时不会失败:
padded_data = pad(data, AES.block_size, 'pkcs7')
cipher = AES.new(self.hashed_key.encode("utf8"), AES.MODE_CBC, self.iv.encode("utf8"))
encrypted = cipher.encrypt(padded_data)

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);
© www.soinside.com 2019 - 2024. All rights reserved.