Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP MCRYPT_RIJNDAEL_128 encryption in C#

I'm trying to rewrite this function in C#. but the C# output mismatches the php

PHP version

// Encrypt data using AES128-cbc
function encrypt($data, $key, $iv) {
    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
    mcrypt_generic_init($cipher, $key, $iv);
    $multipass = mcrypt_generic($cipher, $data);
    mcrypt_generic_deinit($cipher);
    return $multipass;
}

C# Version

public static string encrypt(string encryptionString, string iv, string key)
{
    byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString);
    var rijn = SymmetricAlgorithm.Create();
    rijn.KeySize = 128;
    rijn.Mode = CipherMode.CBC;
    var ms = new MemoryStream();
    var cs = new CryptoStream(ms, rijn.CreateEncryptor(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(iv)), CryptoStreamMode.Write);
    cs.Write(clearTextBytes, 0, clearTextBytes.Length);
    cs.Close();
    var tmp = Encoding.UTF8.GetString(ms.ToArray());
    return tmp;
}
like image 760
nullException Avatar asked Sep 04 '13 16:09

nullException


2 Answers

Encrypt/Decrypt using PHP:

class Cipher {
    private $key, $iv;
    function __construct() {
        $this->key = "edrtjfjfjlldldld";
        $this->iv = "56666852251557009888889955123458";
    }
    function encrypt($text) {

        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
        $padding = $block - (strlen($text) % $block);
        $text .= str_repeat(chr($padding), $padding);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->key, $text, MCRYPT_MODE_CBC, $this->iv);

        return base64_encode($crypttext);
    }

    function decrypt($input) {
        $dectext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->key, base64_decode($input), MCRYPT_MODE_CBC, $this->iv);
        return $dectext;
    }
}

Encrypt/Decrypt using C#:

public class RijndaelSimple
    {
        const string iv = "56666852251557009888889955123458";
        const string key = "edrtjfjfjlldldld";

        static public String EncryptRJ256(string plainText)
        {
            var encoding = new UTF8Encoding();
            var Key = encoding.GetBytes(key);
            var IV = encoding.GetBytes(iv);
            byte[] encrypted;

            using (var rj = new RijndaelManaged())
            {
                try
                {
                    rj.Padding = PaddingMode.PKCS7;
                    rj.Mode = CipherMode.CBC;
                    rj.KeySize = 256;
                    rj.BlockSize = 256;
                    rj.Key = Key;
                    rj.IV = IV;

                    var ms = new MemoryStream();

                    using (var cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
                    {
                        using (var sr = new StreamWriter(cs))
                        {
                            sr.Write(plainText);
                            sr.Flush();
                            cs.FlushFinalBlock();
                        }
                        encrypted = ms.ToArray();
                    }
                }
                finally
                {
                    rj.Clear();
                }
            }

            return Convert.ToBase64String(encrypted);
        }

        static public String DecryptRJ256(string input)
        {
            byte[] cypher = Convert.FromBase64String(input);

            var sRet = "";

            var encoding = new UTF8Encoding();
            var Key = encoding.GetBytes(key);
            var IV = encoding.GetBytes(iv);

            using (var rj = new RijndaelManaged())
            {
                try
                {
                    rj.Padding = PaddingMode.PKCS7;
                    rj.Mode = CipherMode.CBC;
                    rj.KeySize = 256;
                    rj.BlockSize = 256;
                    rj.Key = Key;
                    rj.IV = IV;
                    var ms = new MemoryStream(cypher);

                    using (var cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
                    {
                        using (var sr = new StreamReader(cs))
                        {
                            sRet = sr.ReadLine();
                        }
                    }
                }
                finally
                {
                    rj.Clear();
                }
            }

            return sRet;
        }

    }
like image 99
Melad Avatar answered Oct 21 '22 14:10

Melad


Two issues with your C# code.

  1. You should not be encoding the contents of your MemoryStream to UTF8. The output of the CryptoStream is binary and will not convert properly. Either return a byte[], or if you really want a string, encode the output to Hex or Base64.

  2. You need to set the padding mode via rijn.Padding = PaddingMode.Zeros;. Although it's not clearly stated, PHP pads data up to the block size using 0's. The default for padding for SymmetricAlgorithm is PKCS7.

Also note that the signatures of your PHP and C# methods are different. The parameter order for your PHP function is data, key, iv while the C# method is data, iv, key. If you're still having an issue after the changes I've listed above, it may be that your IV and key are reversed when calling your C# encrypt method.

like image 35
Syon Avatar answered Oct 21 '22 13:10

Syon