Python AES 加密显示与原始 C# 代码不同的结果

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

下面的代码是我的加密C#代码

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

  public static string Encrypt(string value)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(value);

            Aes aes = Aes.Create();

            Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes("aaaabbbbccccddddffffeeee", new byte[13] { 73, 118, 97, 110, 32, 77, 101, 100, 118, 101, 100, 101, 118 });


            aes.Key = rfc2898DeriveBytes.GetBytes(32);
            aes.IV = rfc2898DeriveBytes.GetBytes(16);


            MemoryStream memoryStream = new MemoryStream();
            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cryptoStream.Write(bytes, 0, bytes.Length);
                cryptoStream.Close();
            }

            value = Convert.ToBase64String(memoryStream.ToArray());
            return value;
        }

其结果

Console.WriteLine(加密(“你好”));

就是下面这个

t2FQeBN/POo+mNW5MgIC4Q==

这是我的 Python 代码,相当于上面的 C# 代码,

from Crypto.Protocol.KDF import PBKDF2
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64

password = "aaaabbbbccccddddffffeeee"
salt = bytes([73, 118, 97, 110, 32, 77, 101, 100, 118, 101, 100, 101, 118])

def encrypt(value):
    handledByte = value.encode()

    key = PBKDF2(password, salt, 32)
    iv = bytes([204, 21, 82, 91, 78, 119, 26, 182, 218, 43, 182, 239, 169, 70, 216, 137])

    cipher = AES.new(key, AES.MODE_CBC, iv=iv)

    raw = pad(handledByte, AES.block_size)
    ciphered_data = cipher.encrypt(raw)

    return(base64.b64encode(iv + ciphered_data).decode())

 

其结果

打印(加密(“你好”));

就是下面这个

zBVSW053GrbaK7bvqUbYidcdcXlpDBKMqq8EGqN2eac=

我知道我错过了一些东西,但无论如何我找不到它。我将不胜感激任何帮助。

python c# encryption aes pycryptodome
1个回答
0
投票

对于明文,使用不同的编码,C# 代码中的 UTF-16LE(称为

Unicode
)和 Python 代码中的 UTF-8(
encode()
默认值)。对于 Python 中的 UTF-16LE,必须使用
value.encode('utf-16le')

此外,C# 代码使用 PBKDF2 派生 IV,而 Python 代码应用硬编码 IV(与派生的 IV 相同,但当然这仅适用于这些特定的 PBKDF2 参数,并且通常是不正确的)。
Python 代码连接了 IV 和密文,而 C# 代码则没有(这不是必需的,因为 IV 是使用 PBKDF2 导出的)。

如果更正此问题,Python 代码将给出与 C# 代码相同的结果:

from Crypto.Protocol.KDF import PBKDF2
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import base64

password = "aaaabbbbccccddddffffeeee"
salt = bytes([73, 118, 97, 110, 32, 77, 101, 100, 118, 101, 100, 101, 118])

def encrypt(value):
    handledByte = value.encode('utf-16le') # Fix 1: apply UTF-16LE

    keyIv = PBKDF2(password, salt, 32+16) # Fix 2: Derive key and IV
    key = keyIv[:32]
    iv = keyIv[32:]

    cipher = AES.new(key, AES.MODE_CBC, iv=iv)

    raw = pad(handledByte, AES.block_size)
    ciphered_data = cipher.encrypt(raw)

    return(base64.b64encode(ciphered_data).decode()) # Fix 3: Don't concatenate IV and ciphertext

print(encrypt('hello')) # t2FQeBN/POo+mNW5MgIC4Q==
© www.soinside.com 2019 - 2024. All rights reserved.