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

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

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=

请问有谁知道如何使这两个代码的输出相同?

python php encryption aes
1个回答
0
投票

问题出在您的 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";
?>
© www.soinside.com 2019 - 2024. All rights reserved.