3

I have decrypted the string "12345678901234567890123456789012" in C#, using AES

The string is 32 bytes and the resulting "array" (see code) is of length 48, so both are even multiples of 16.

key is "b14ca5898a4e4133bbce2ea2315a1916"

    public static string EncryptString(string key, string plainInput)
    { 
        byte[] emptyIv = new byte[16];
        byte[] array;
        List<byte> result;
        using (Aes aes = Aes.Create())
        {
            aes.Key = Encoding.UTF8.GetBytes(key);
            aes.Mode = CipherMode.CBC;
            aes.BlockSize = 128;
            aes.Padding = PaddingMode.PKCS7;
            //aes.GenerateIV(); 
            aes.IV = emptyIv;

            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                    {
                        streamWriter.Write(plainInput);
                    }

                    array = memoryStream.ToArray();
                }
            }

            result = new List<byte>(aes.IV);       #EDIT AFTER COMMENT
            result.AddRange(new List<byte>(array));#EDIT AFTER COMMENT
        } 
        return Base64UrlEncoder.Encode(result.ToArray());           
    }

Im trying to decrypt it in my python-code

import base64
import hashlib
from Cryptodome import Random
from Cryptodome.Cipher import AES

#...

def decrypt( self, encryptedB64):         
    encrypted = base64.b64decode(encryptedB64 + '===')
    iv = encrypted[:AES.block_size]
    cipher = AES.new(self.key, AES.MODE_CBC, iv ) 
    decrypted = cipher.decrypt(encrypted[AES.block_size:]) #<-- error on this line
    return AESEncryptionHelper._unpad(decrypted)

When I try to decrypt it (cipher.decrypt(...) I get the error message:

"Data must be padded to 16 byte boundary in CBC mode".

I have read that data must be of multiple 16, but Im not really clear on what data needs to be of multiple 16.

I have pasted in my resulting (base64-encoded) encrypted string into this website (no IV, 256bits, CBC-mode, see key above) and it works well.

So to keep it short, what am I doing wrong?

Cowborg
  • 2,645
  • 3
  • 34
  • 51
  • 2
    Since the IV is needed for encryption and decryption, the IV is usually concatenated with the ciphertext. The IV is typically placed before the ciphertext. The result is sent to the recipient, who separates both parts. Since the IV isn't secret, it doesn't need to be encrypted. It seems that in the C# code this concatenation is missing, whereas in the Python code it is expected. – Topaco Feb 06 '20 at 09:22
  • Hi Topaco, Thanks for your reply! So Im now calling B64Endode with the array [iv,array] see updated post. That gives me the encrypted base64-string: "AAAAAAAAAAAAAAAAAAAAAG3b8Z_dnL7drQipIt2LlmOdItT6mlpsMAbnjQZSgKLj_RKtgFh8mAweGrkIvzJsGg" , but I get same error message from decryption – Cowborg Feb 06 '20 at 09:49
  • 1
    The C# code uses Base64url encoding, the Python code uses Base64 encoding. Both codes must use the _same_ encoding. As a workaround the posted string can be manually converted from Base64url to Base64 by replacing _ with /, i.e. use AAAAAAAAAAAAAAAAAAAAAG3b8Z/dnL7drQipIt2LlmOdItT6mlpsMAbnjQZSgKLj/RKtgFh8mAweGrkIvzJsGg. – Topaco Feb 06 '20 at 10:23
  • 1
    A base64 string should have a length dividable by 4. The string you show have length 86 and is thus an invalid base64 string. The `(encryptedB64 + '===')` statement makes it passable, but properbly don't correct an invalid base64 string. – Ebbe M. Pedersen Feb 06 '20 at 10:27
  • Now Im using the correct B64-encoder, (cant remember why I changed it, sorry). I get a encrypted string like so "AAAAAAAAAAAAAAAAAAAAAG3b8Z/dnL7drQipIt2LlmOdItT6mlpsMAbnjQZSgKLj/RKtgFh8mAweGrkIvzJsGg==", m python code does not give any errors, but returns b'/\x07\xc3\xd4\xb0v5\xaa\xcc\xab\x17m4L\x19\xfb\x7f\x92:\xd1\xeb\xac6\xe1\xc9\x9dy\x82\xb8', it doesnt seem to be "decodable" to a utf-8-string, but Im not a python-programmer... The string is still decryptable on the website (link in post) – Cowborg Feb 06 '20 at 11:59
  • 1
    I can decrypt this ciphertext on my machine. Might be a problem in the part not posted. How is the key encoded in the Python code (also utf8 as in the C# code)? – Topaco Feb 06 '20 at 12:29
  • O, sounds promising. (self.key = hashlib.sha256(key.encode('utf-8')).digest()) – Cowborg Feb 06 '20 at 12:33
  • @Topaco: OK, should be "self.key = key.encode('utf-8')". Now everything works, it was basically: (1) [iv+array], (2) encoding(base64Url-> base64Normal (3) Key was strange... i you want the creds, please write that as an answer and Ill set it as the correct answer – Cowborg Feb 06 '20 at 12:52
  • If you're explicitly use different algorithms on both sides, I'm really wondering if this is not all simple copy-paste coding. I really don't get code examples such as above. Are you really unable to perform a comparison between the two code fragments? Why aren't even the functions and parameter names matching? Why do you write that `b14ca5898a4e4133bbce2ea2315a1916` is a 32 byte key? Have you *heard* of hexadecimals? – Maarten Bodewes Feb 06 '20 at 14:45
  • 2
    @Maartens: Its solved now. This was just to get the encryption/decryption working, not production code. What are you trying to achieve with a bad attitude? – Cowborg Feb 06 '20 at 18:28

0 Answers0