For the past day I have been looking for a solution to transfer
encrypted information between a PHP web application and a C# desktop
application.
This requires that both systems use the same algorithm, key and init vector (IV)
This isn’t as easy as it sounds. The slightest difference in the
setup of either system means that the encrypted information cannot be
decoded on the other end and makes it basically useless.
(The following PHP code has been modified after some useful debugging and comments from Serge N.)
//Encryption function
function mc_encrypt($encrypt, $key, $iv)
{
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $encrypt);
$encode = base64_encode($encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $encode;
}
//Decryption function
function mc_decrypt($decrypt, $key, $iv)
{
$decoded = base64_decode($decrypt);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $decoded);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return trim($decrypted);
}
//Usage in PHP
$original = "original message";
$key = "abcdefg_abcdefg_abcdefg_abcdefg_";
$iv = "abcdefg_abcdefg_";
$keysize = 128;
$enced = mc_encrypt(stripslashes($original), $key, $iv);
echo "Encrypted:
".$enced."
";
$unced = mc_decrypt($enced, $key, $iv);
echo "Decrypted:
".$unced."
";
That is the PHP code done. We can generate a key and then at any point use the decrypt function to unencode it.
Now the trick is getting the exact same functionality in .NET (with C#)
I found that the class below does it pretty well (this uses the default Rijndael algorithm which is 128 in C#)
public static class Encrypter
{
public static String EncryptIt(String s, byte[] key, byte[] IV)
{
String result;
RijndaelManaged rijn = new RijndaelManaged();
rijn.Mode = CipherMode.ECB;
rijn.Padding = PaddingMode.Zeros;
using (MemoryStream msEncrypt = new MemoryStream())
{
using (ICryptoTransform encryptor = rijn.CreateEncryptor(key, IV))
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(s);
}
}
}
result = Convert.ToBase64String(msEncrypt.ToArray());
}
rijn.Clear();
return result;
}
public static String DecryptIt(String s, byte[] key, byte[] IV)
{
String result;
RijndaelManaged rijn = new RijndaelManaged();
rijn.Mode = CipherMode.ECB;
rijn.Padding = PaddingMode.Zeros;
using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(s)))
{
using (ICryptoTransform decryptor = rijn.CreateDecryptor(key, IV))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader swDecrypt = new StreamReader(csDecrypt))
{
result = swDecrypt.ReadToEnd();
}
}
}
}
rijn.Clear();
return result;
}
}
//Usage
Encoding byteEncoder = Encoding.UTF8;
byte[] rijnKey = byteEncoder.GetBytes("abcdefg_abcdefg_abcdefg_abcdefg_");
byte[] rijnIV = byteEncoder.GetBytes("abcdefg_abcdefg_");
String message = "original message";
String encrypted = Encrypter.EncryptIt(message, rijnKey, rijnIV);
String decrypted = Encrypter.DecryptIt(encryption, rijnKey, rijnIV);
Console.WriteLine("Original: "+message);
Console.WriteLine("Encrypted: "+encrypted);
Console.WriteLine("Decrypted: "+decrypted);
I hope this shortens someone’s search process when trying to do this.
PS. Yes this is my first try at using the [ code ] containers in
Posterous (not the easiest thing in the world but after some tweaking
eventually got the code to appear here nicely)
TAKEN from http://blog.nikoroberts.com/post/45834708375/php-mcrypt-and-c-encryptor , all credits goes there