I have to implement a system where we send an encrypted message to another application which we do not control. We use C# whereas the other application uses PHP.
The first thing I wanted to make sure was that, for the same input, I would get the same encrypted output in both C# and PHP.
To be clear, I can not change the PHP code used by the receiving application.
I have used a PHP example using openssl_encrypt (CBC) and a C# example using system.security.cryptography.RijndaelManaged.
PHP test code
$opts=OPENSSL_RAW_DATA;
$plain_text = "wetestendit";
$key = "12345678911234567892123456789312";
$iv = "1234567890123456";
$opts=OPENSSL_RAW_DATA;
$plaintext = "wetestendit";
$key = "12345678911234567892123456789312";
$iv = "1234567890123456";
$saltDing = "Salted__12345678";
$encrypt = openssl_encrypt($plain_text, "AES-256-CBC", $key, $opts, $iv);
$encrypt2 = openssl_encrypt($plain_text, "AES-256-CBC", $key, 0, $iv);
echo $encrypt . "\n";
echo $encrypt2 . "\n";
When using the RAW_Data output format my test gives: ?Y09?¬???}?)?v? as output. When using 0 the output is base64 encoded: x1kwOeUf3fmUfdQpknbjkw==
If I use the following C# function with the same key, iv and input
private 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;
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();
ms.Close();
return Encoding.ASCII.GetString(encoded);
}
I get ?Y09?\u001f???}?)?v?? as the result. If I base64 the byte array first, the output is x1kwOeUf3fmUfdQpknbjkw==, the same as PHP. Unfortunately the PHP code uses raw output, so I need make sure those are the same.
Interestingly enough the individual bytes, using PHP ord and inspecting the c# byte array, are the same. The output however, even though it looks similar, isn't.
I've tried all the paddingmodes in C# but none of them gave the exact same rsult as PHP.
Is there a way to make sure that both C# and PHP give the same output?