0

Python Encryption:

salt = 16 * b'\0'
keyIV = PBKDF2(Config.SECRET, salt).read(48)
key = keyIV[:32]
iv = keyIV[-16:]
aes = AES.new(key, AES.MODE_CBC, iv)

# padding
length = 16 - (len(textToEncrypt) % 16)
print(len(textToEncrypt))
textToEncrypt += length * b'\0'

encrypted = aes.encrypt(textToEncrypt)
encoded = base64.b64encode(encrypted)
return encoded

And here is my C# decryption:

        textToDecrypt = textToDecrypt.Replace(" ", "+");
        byte[] bytesToDecrypt = Convert.FromBase64String(textToDecrypt);
        string decryptedText;
        using (Aes aes = Aes.Create())
        {
            byte[] salt = new byte[16];
            Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(Config.SECRET, salt);
            aes.Padding = PaddingMode.PKCS7;
            aes.Mode = CipherMode.CBC;
            aes.Key = crypto.GetBytes(32);
            aes.IV = crypto.GetBytes(16);
            using (MemoryStream mStream = new MemoryStream())
            {
                using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cStream.Write(bytesToDecrypt, 0, bytesToDecrypt.Length);
                }
                decryptedText = Encoding.Unicode.GetString(mStream.ToArray());
            }
        }
        return decryptedText;

EDIT

Following @kelalaka answer, I'm now able to encrypt from C# and decrypt that string in python successfully, but not vice versa. That is, if I encrypt a string in python, and try to decrypt that encryption in C# I get an exception: "Bad PKCS7 padding. Invalid length 0". My python encryption is much shorter than what I get in C# using the same cipherText, iv, and key.

nblandfo
  • 31
  • 8
  • 2
    Your IV is incorrect in Python that makes the first block garbage. You need to call `PBKDF2(Config.SECRET, salt).read(48)` and divide it. Actually, it is better if you prepend the IV to the ciphertext as a usual practice. Why do you use CBC? – kelalaka Feb 07 '20 at 22:29
  • What do you mean by divide it? When I change the read it says the IV has to be 16 bytes. I'm new to cryptography, I'm using CBC because that's why I found in the example I'm following. I have tried CFB but get similar results. – nblandfo Feb 07 '20 at 22:44
  • 1
    In C# the successive call to GetBytes will give you new values. In python, the key's first 16 byte will be the same as IV. Generate 48 bit, take 32 as key and rest as IV. Normally, the IV sent together with the ciphertext without encryption. Concantrate in modern mode of operations like AES-GCM. – kelalaka Feb 07 '20 at 22:47
  • Dividing it solved the issue. Thanks for explaining that to me! – nblandfo Feb 07 '20 at 23:16
  • 1
    Write your answer? – kelalaka Feb 07 '20 at 23:49
  • @nblandfo: CBC mode has various security problems, if you have any choice you should not use it these days. Suggested alternative would be AES-GCM – mat Feb 11 '20 at 10:43
  • Unfortunately Xamarin.ios doesn't support GCM yet. I've gotten closer but still having issues, edited above – nblandfo Feb 11 '20 at 22:42

0 Answers0