This is my very first attempt at cryptography and I am having trouble with porting the encryption from PHP to C#.
I had searched the internet for a working solution to my problem but everything I have tried does not work. I am getting different results between the two languages.
In PHP I have the following code:
function encrypt($Key, $strToEncrypt){
$md5Key = md5(pack("H*", $Key));
$md5Iv = md5($Key);
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding = $block - (strlen($strToEncrypt) % $block);
$strToEncrypt .= str_repeat(chr($padding), $padding);
$enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $md5Key, $strToEncrypt, MCRYPT_MODE_CBC, $md5Iv);
$enc2 = base64_encode($enc);
return $enc2;
}
and in C# the following code:
public string Encrypt(string strToEncrypt)
{
string ret;
var pKey = PackH(_appkey);
var md5Key = CalcMd5(pKey);
var iv = CalcMd5(_appkey);
var enc =Encoding.UTF8;
var eIv = enc.GetBytes(iv);
var eKey = enc.GetBytes(md5Key);
using (var rij = new RijndaelManaged { BlockSize = 256, KeySize = 256, IV = eIv, Key = eKey, Mode = CipherMode.CBC, Padding = PaddingMode.Zeros})
using (var memoryStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, rij.CreateEncryptor(eKey, eIv), CryptoStreamMode.Write))
{
using (var sw = new StreamWriter(cryptoStream))
{
sw.Write(strToEncrypt);
}
ret = Convert.ToBase64String(memoryStream.ToArray());
}
return ret;
}
The C# Pack function:
protected byte[] PackH(string hex)
{
if ((hex.Length % 2) == 1) hex += '0';
var bytes = new byte[hex.Length / 2];
for (var i = 0; i < hex.Length; i += 2)
{
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
}
return bytes;
}
And the C# CalcMd5 function:
protected string CalcMd5(string textToEnc)
{
var sB = new StringBuilder();
using (var mdHash = MD5.Create())
{
var cHash = mdHash.ComputeHash(Encoding.UTF8.GetBytes(textToEnc));
foreach (byte t in cHash)
{
sB.Append(t.ToString("x2"));
}
}
return sB.ToString();
}
I have another CalcMd5 function that takes in a byte[] (it is like the one above but does not have the GetBytes part).
The keys and the string that needs encrypting are the same both in PHP and C#:
The Key: "24acd2fcc7b20b8bd33ff45176f03061a09b729487e10d2dd38ab917" and
The string that I want to encode: "110114135AB96637711100"
In C# the result of the function is:"LHTqpxCJrONmbDdUFHyUZZUVf94z1RmSXWo85/wyEew=" while in PHP is: "5MkCjfs0vp2HSKdY5XPUAuV68YsrP31Q+ddZsd5p7Sc=".
I have tried modifying the padding mode in C#, also tried different methods found on the stackoverflow site but none of them works.
I have checked and the final key and Iv that are passed to the mcrypt function and RijndaelManaged function are the same and both have 32 byte size.
The oddly part is that the decryption functions are working very well (it is working to decrypt the PHP encrypted string with C# function and the other war around C# encrypted string is decrypted with the PHP function).
Could it be a problem with the encoding? Or maybe the padding? Or is there something else that I have overlooked?