Sylver11
Sylver11

Reputation: 199

C# RijndaelManaged vs Python Crypto.Cipher AES + CBC

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:

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;
  }
}

Upvotes: 2

Views: 709

Answers (1)

Sylver11
Sylver11

Reputation: 199

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

Upvotes: 1

Related Questions