Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decrypting in Python an string encrypted using .NET

I am trying to encrypt a string using C# and decrypt it using Python. The encryption/decryption part works as expected (i.e. I am able to decrypt the string I originally encrypted). However the string returned by Python has 2 extra bytes at the beginning and each character is separated by a space.

**Original string** (before encryption -- encrypted using C#) = "Something you want to keep private with AES"

**Decrypted string** (using Python) = "��S o m e t h i n g  y o u   w a n t   t o   k e e p   p r i v a t e   w i t h  A E S"

Why am I getting these two extra bytes at the beginning of the string? Why all those spaces in the decrypted string? Any idea why?

Thanks!

Encryption with C#

public static string Encrypt<T>(string value, string password, string salt)
         where T : SymmetricAlgorithm, new()
{
    DeriveBytes rgb = new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(salt));

    SymmetricAlgorithm algorithm = new T();

    byte[] rgbKey = rgb.GetBytes(algorithm.KeySize >> 3);
    byte[] rgbIV = rgb.GetBytes(algorithm.BlockSize >> 3);

    ICryptoTransform transform = algorithm.CreateEncryptor(rgbKey, rgbIV);

    using (MemoryStream buffer = new MemoryStream())
    {
        using (CryptoStream stream = new CryptoStream(buffer, transform, CryptoStreamMode.Write))
        {
            using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
            {
                writer.Write(value);
            }
        }

        return Convert.ToBase64String(buffer.ToArray());
    }
}


string plain = "Something you want to keep private with AES";
string encrypted = CipherUtility.Encrypt<AesManaged>(plain, "password", "salt");

Decryption with Python + pycrypto

import base64, sys
import Crypto.Cipher.AES

password = base64.b64decode('PSCIQGfoZidjEuWtJAdn1JGYzKDonk9YblI0uv96O8s=') # See rgbKey
salt = base64.b64decode('ehjtnMiGhNhoxRuUzfBOXw==') # See rgbIV
aes = Crypto.Cipher.AES.new(password, Crypto.Cipher.AES.MODE_CBC, salt)
text = base64.b64decode('QpHn/fnraLswwI2Znt1xTaBzRtDqO4V5QI78jLOlVsbvaIs0yXMUlqJhQtK+su2hYn28G2vNyLkj0zLOs+RIjElCSqJv1aK/Yu8uY07oAeStqRt4u/DVUzoWlxdrlF0u')

print aes.decrypt(text)
like image 344
Martin Avatar asked May 12 '12 17:05

Martin


1 Answers

The string is encoded to bytes using the UTF-16 encoding. The first two bytes are a BOM. Then each character is encoded to two bytes.

From the documentation for Encoding.Unicode:

Gets an encoding for the UTF-16 format using the little endian byte order.

To get the original string you need to decode it back from UTF-16 bytes to a Unicode string.

print aes.decrypt(text).decode('utf-16')
like image 68
Mark Byers Avatar answered Oct 15 '22 18:10

Mark Byers