简体   繁体   中英

How to decrypt a AES encrypted data of C# in Python?

I am trying to encrypt a text in C# and then trying to decrypt the data in Python but I am unable to decrypt the C# encrypted data in python. I think maybe I am unable to get the same IV as I am using in C#. I don't know where I am getting wrong.

class AesEncryption
{
    public static void Main()
    {
        var original = "Here is some data to encrypt!";



        using (var myAes = Aes.Create())
        {
            var key = "My private key";
            myAes.Key = Encoding.ASCII.GetBytes(key);
            myAes.Mode = CipherMode.CBC;
            myAes.IV = new byte[16];

            // Encrypt the string to an array of bytes.
            var encrypted = EncryptStringToBytes_Aes(original, myAes.Key, myAes.IV);

            Console.WriteLine("Encrypted:   {0}", encrypted);

            // Decrypt the bytes to a string.
            var roundtrip =
                DecryptStringFromBytes_Aes(System.Convert.FromBase64String(encrypted), myAes.Key, myAes.IV);

            //Display the original data and the decrypted data.
            Console.WriteLine("Original:   {0}", original);
            Console.WriteLine("Round Trip: {0}", roundtrip);
        }
    }

    private static string EncryptStringToBytes_Aes(string plainText, byte[] key, byte[] iv)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException(nameof(plainText));
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException(nameof(key));
        if (iv == null || iv.Length <= 0)
            throw new ArgumentNullException(nameof(iv));

        // Create an Aes object
        // with the specified key and IV.
        using var aesAlg = Aes.Create();
        aesAlg.Key = key;
        aesAlg.IV = iv;

        // Create an encryptor to perform the stream transform.
        var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        // Create the streams used for encryption.
        using var msEncrypt = new MemoryStream();
        using var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
        using (var swEncrypt = new StreamWriter(csEncrypt))
        {
            //Write all data to the stream.
            swEncrypt.Write(plainText);
        }

        var encrypted = msEncrypt.ToArray();

        // Return the encrypted bytes from the memory stream.
        return Convert.ToBase64String(encrypted);
    }

    private static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] key, byte[] iv)
    {
        // Check arguments.
        if (cipherText == null || cipherText.Length <= 0)
            throw new ArgumentNullException(nameof(cipherText));
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException(nameof(key));
        if (iv == null || iv.Length <= 0)
            throw new ArgumentNullException(nameof(iv));

        // Declare the string used to hold
        // the decrypted text.
        string plaintext;

        // Create an Aes object
        // with the specified key and IV.
        using (var aesAlg = Aes.Create())
        {
            aesAlg.Key = key;
            aesAlg.IV = iv;

            // Create a decryptor to perform the stream transform.
            var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for decryption.
            using (var msDecrypt = new MemoryStream(cipherText))
            {
                using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (var srDecrypt = new StreamReader(csDecrypt))
                    {
                        // Read the decrypted bytes from the decrypting stream
                        // and place them in a string.
                        plaintext = srDecrypt.ReadToEnd();
                    }
                }
            }
        }

        return plaintext;
    }
}

I am using IV iv = as new byte[16]; In the above code, I am checking what is the Encrypted text being generated during the process of encryption and decryption and trying to match that in my python encryption.

import base64
import binascii
import hashlib

from Crypto.Cipher import AES


def r_pad(payload, block_size=16):
    length = block_size - (len(payload) % block_size)
    return payload + chr(length) * length


key = "My private key"
body = "Here is some data to encrypt!"
iv = binascii.unhexlify(16 * "00")
length = len(body)
encoded_key = hashlib.sha256(key.encode()).digest()
data_from_encryption = r_pad(body).encode('utf-8')

encrypted_data = AES.new(encoded_key, AES.MODE_CBC, iv).encrypt(data_from_encryption)
encrypted_data_to_base64_str = base64.b64encode(encrypted_data).decode('utf-8')
print("Encrypted data: ", encrypted_data_to_base64_str)
bytes_to_decrypt = base64.decodebytes(encrypted_data_to_base64_str.encode())
decrypted_data = AES.new(encoded_key, AES.MODE_CBC, iv).decrypt(bytes_to_decrypt)[:length]
decode_str = decrypted_data.decode('utf-8')
print(decode_str)

I tried to user different value of IV iv = binascii.unhexlify(16 * "00")

but can't get the same encrypted text in both the codes. I also know what r_pad function doing in python but if I don't user it Python raises Exception about my data not being padded according to 16 bit

Can anybody help and tell me where I am getting wrong?

In the C# code, the key is the ASCII encoding of key , but in the Python code it is the SHA-256 hash of key .

So that the Python code produces the same ciphertext, simply replace:

encoded_key = key.encode('ascii')

Note the following issues:

  • A static IV is insecure. Usually, a random IV is generated for each encryption and passed along with the ciphertext (usually concatenated).
  • If the key is to be derived from a password, then a reliable key derivation function such as Argon2 or PBKDF2 should be used instead of a digest.
  • PyCryptodome supports padding in a dedicated module: Crypto.Util.Padding

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM