Rijndael 256 Encrypt/decrypt between c# and php?
Asked Answered
V

2

11

UPDATED

I have made the changes to the C# code so it uses a block size of 256. but now the hello world looks like this http://pastebin.com/5sXhMV11 and I cant figure out what I should use with rtrim() to get ride of the mess at the end.

Also when you say the IV should be random, by this do you mean don't use the same IV more then once or is the way I have coded it wrong?

Thanks again!

Hi,

I'm trying to decrypt a string with PHP that was encrypted in C#. I can't seem to get PHP to decrypt it using mcrypt and could do with some help please. I get the following error with php so I am guessing I'm not setting the IV correctly.

Error: The IV parameter must be as long as the blocksize

Both functions use the same cipher, key, IV and set to CBC mode:

encrypted text from c# = UmzUCnAzThH0nMkIuMisqg==
key 32 long = qwertyuiopasdfghjklzxcvbnmqwerty
iv 16 long = 1234567890123456

C#

    public static string EncryptString(string message, string KeyString, string IVString)
    {
        byte[] Key = ASCIIEncoding.UTF8.GetBytes(KeyString);
        byte[] IV = ASCIIEncoding.UTF8.GetBytes(IVString);

        string encrypted = null;
        RijndaelManaged rj = new RijndaelManaged();
        rj.Key = Key;
        rj.IV = IV;
        rj.Mode = CipherMode.CBC;

        try
        {
            MemoryStream ms = new MemoryStream();

            using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
            {
                using (StreamWriter sw = new StreamWriter(cs))
                {
                    sw.Write(message);
                    sw.Close();
                }
                cs.Close();
            }
            byte[] encoded = ms.ToArray();
            encrypted = Convert.ToBase64String(encoded);

            ms.Close();
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
        catch (UnauthorizedAccessException e)
        {
            Console.WriteLine("A file error occurred: {0}", e.Message);
            return null;
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: {0}", e.Message);
        }
        finally
        {
            rj.Clear();
        }

        return encrypted;
    }

PHP

var $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
var $mcrypt_mode = MCRYPT_MODE_CBC;

function decrypt($key, $iv, $encrypted)
{
    $encrypted = base64_decode($encrypted);

    $decrypted = rtrim(mcrypt_decrypt($this->mcrypt_cipher, $key, $encrypted, $this->mcrypt_mode, $iv), "\0");;
    return $decrypted;
}

Thanks

Vittle answered 7/8, 2010 at 20:34 Comment(2)
The IV should really be randomized. It defeats the purpose of having one if it's not.Gulfweed
Rijndael with 256-bit blocks is non-standard.Beeler
O
11

If you want to use Rijndael256 in your C# application you have to set the BlockSize to 256.

RijndaelManaged rj = new RijndaelManaged();
rj.BlockSize = 256;

And then your iv has to be 256 bits long as well.
see SymmetricAlgorithm.BlockSize Property


Or the other way round: Currently your C# application uses Rijndael128 and so must your php script.

<?php
class Foo {
  protected $mcrypt_cipher = MCRYPT_RIJNDAEL_128;
  protected $mcrypt_mode = MCRYPT_MODE_CBC;

  public function decrypt($key, $iv, $encrypted)
  {
    $iv_utf = mb_convert_encoding($iv, 'UTF-8');
    return mcrypt_decrypt($this->mcrypt_cipher, $key, base64_decode($encrypted), $this->mcrypt_mode, $iv_utf);
  }
}



$encrypted = "UmzUCnAzThH0nMkIuMisqg==";
$key = "qwertyuiopasdfghjklzxcvbnmqwerty";
$iv = "1234567890123456";

$foo = new Foo;
echo $foo->decrypt($key, $iv, $encrypted);

prints hello world

Orang answered 7/8, 2010 at 21:1 Comment(4)
I know it's not your fault, but the IV should really be randomized. It defeats the purpose of having one if it's not.Gulfweed
agreed. see msdn.microsoft.com/en-us/library/… and docs.php.net/function.mcrypt-create-ivOrang
Can you see this please ? #18909113Sidney
True but its an example ;)Middleaged
M
-1

Encrypt using PHP;

/Generate public key for encrytion
$path = "keys/";

    $crt = openssl_x509_read(file_get_contents($path."cert.crt"));
    $publickey = openssl_get_publickey($crt);

    //Encrypt using public key
    openssl_public_encrypt($source, $crypted, $publickey);

    //openssl_private_encrypt($source, $crypted, $privkey);
    echo base64_encode($crypted);

Decrypt using C#

    X509Certificate2 x509cert = new X509Certificate2(pKeyFilename);
    RSACryptoServiceProvider.UseMachineKeyStore = false;
    RSACryptoServiceProvider crypt = (RSACryptoServiceProvider)x509cert.PrivateKey;                

    byte[] decrypted = crypt.Decrypt(Convert.FromBase64String(data), false);
    return ASCIIEncoding.UTF8.GetString(decrypted);

where pKeyFilename is a Personal Information Exchange File created with the certificate file cert.crt. This examples uses a AES-256 encryption.

Middleaged answered 9/9, 2011 at 10:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.