2

I've been banging my head against the wall for a couple of days now and was hoping someone could point out the obvious. I am trying to match the RijndaelManaged encryption of C# with that of Python using Crypto.Cipher.

Problem: Despite everything being equal I am receiving two different encrypted outputs.

These are the values passed:

  • encryption key as string (32 characters)
  • value to be encrypted already padded as string (in this case 32 characters)

Python 3:

import os import base64 from Crypto.Cipher import AES iv = 'wdp0hP2WRKWsuP8B' def fix_binary_data_length(binary_value): block_length = 16 binary_value_length = len(binary_value) length_with_padding = ( binary_value_length + (block_length - binary_value_length) % block_length ) return binary_value.ljust(length_with_padding, b'=') def encrypt(value: str, key: str): binary_iv = iv.encode('UTF-8') binary_value = value.encode('UTF-8') binary_value = fix_binary_data_length(binary_value) binary_key = key.encode('UTF-8') cipher = AES.new(binary_key, AES.MODE_CBC, binary_iv) encrypted_value = cipher.encrypt(binary_value) return encrypted_value 

C#

using System; using System.IO; using System.Linq; using System.Text; using System.Security.Cryptography; public class Crypt { public static string encrypt(string _sValue, string _sKey){ string _sIv = "wdp0hP2WRKWsuP8B"; if (_sKey.Length != 32) { return string.Empty; } using (RijndaelManaged _Rijndael = new RijndaelManaged(){ Mode = CipherMode.CBC, KeySize = 256, BlockSize = 128 }){ byte[] _chEncrypt = Encoding.UTF8.GetBytes(_sValue); using (ICryptoTransform _Encryptor = _Rijndael.CreateEncryptor(Encoding.UTF8.GetBytes(_sKey), Encoding.UTF8.GetBytes(_sIv))) using (MemoryStream _Stream = new MemoryStream()) using (CryptoStream _CryptoStream = new CryptoStream(_Stream, _Encryptor, CryptoStreamMode.Write)){ _CryptoStream.Write(_chEncrypt, 0, _chEncrypt.Length); _CryptoStream.FlushFinalBlock(); return Convert.ToBase64String(_Stream.ToArray()); } } return string.Empty; } } 
5
  • Your C# code won't compile -- you can't return false from a method which returns string. If you haven't even run the code in your question, there's no point in us spending time going through it line-by-line. Please post an actual minimal reproducible example which we -- and you -- can run. Commented Aug 12, 2021 at 8:48
  • @canton7 my apologies I just updated the code. Commented Aug 12, 2021 at 9:25
  • 1
    The generated ciphertexts are trivially different, because you use random IVs. Apart from that you apply different paddings. Btw, the IV derivation is not plausible (truncation of the Base64 encoded data). Commented Aug 12, 2021 at 10:07
  • @Topaco thanks for your response. Regarding the IVs I included the IV generating part for context reasons but when testing I actually pass the same 16 character IV string. The output I get from each one of them is somewhat similar. The python encrypted string: H5DGbNhnJUT/apqzgOvAr2qRG78TgffIrPKhLQMA6T8= and the C# encrypted string: H5DGbNhnJUT/apqzgOvAr/rW+2OxvCq7FVMRWuN/YVs= At about half way they deviate.. does that have to do with the IV? Commented Aug 12, 2021 at 10:28
  • 1
    No, that's the different padding (custom in the Python code, PKCS7 in the C# code). Apply the same padding, preferably PKCS7. PyCryptodome supports padding in a dedicated module, Crypto.Util.Padding. Commented Aug 12, 2021 at 10:33

1 Answer 1

1

Credits to @Topaco for pointing out the obvious ;)

Seems like I did not fully grasp the concept of padding. This is how I got it to work:

import os import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad iv = 'wdp0hP2WRKWsuP8B' def encrypt(value: str, key: str): binary_iv = iv.encode('UTF-8') binary_value = value.encode('UTF-8') binary_key = key.encode('UTF-8') cipher = AES.new(binary_key, AES.MODE_CBC, binary_iv) encrypted_value = cipher.encrypt(pad(binary_value, AES.block_size)) encrypted_value = base64.b64encode(encrypted_value) return encrypted_value 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.