There are already some helpful questions on SO:
- Rijndael 256 Encrypt/decrypt between c# and php?
- Rewrite Rijndael 256 C# Encryption Code in PHP
- Rijndael/AES decryption C# to PHP conversion
However I am still having difficulties with my particular case.
I've tried various methods but end up getting the error "The IV parameter must be as long as the blocksize"
or text that doesn't match the resulting hash.
I don't understand encryption enough to work out what I'm doing wrong.
Here is the php version:
$pass = 'hello';
$salt = 'application-salt';
echo Encrypt('hello', 'application-salt');
function Encrypt($pass, $salt)
{
$derived = PBKDF1($pass, $salt, 100, 16);
$key = bin2hex(substr($derived, 0, 8));
$iv = bin2hex(substr($derived, 8, 8));
return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $pass, MCRYPT_MODE_CBC, $iv);
}
function PBKDF1($pass, $salt, $count, $dklen)
{
$t = $pass.$salt;
$t = sha1($t, true);
for($i=2; $i <= $count; $i++)
{
$t = sha1($t, true);
}
$t = substr($t,0,$dklen-1);
return $t;
}
And the C# version:
Console.WriteLine(Encrypt("hello", "application-salt"));
// output: "Hk4he+qKGsO5BcL2HDtbkA=="
public static string Encrypt(string clearText, string Password)
{
byte[] clearData = System.Text.Encoding.Unicode.GetBytes(clearText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
MemoryStream ms = new MemoryStream();
Rijndael alg = Rijndael.Create();
alg.Key = pdb.GetBytes(32);
alg.IV = pdb.GetBytes(16);
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(clearData, 0, clearData.Length);
cs.Close();
byte[] encryptedData = ms.ToArray();
return Convert.ToBase64String(encryptedData);
}
I want to be able to validate user logins in a new php-based application which will communicate to the same MySQL database as an existing C# application. I intend to encrypt the password and compare the resulting hash to the one stored in the database to authenticate.
Any pointers would be most appreciated.
Edit:
I realize that in the C# function, the PasswordDeriveBytes
is being called and passed a byte array as an argument for which I don't have an analog in the PHP version. I discovered that this originates from a Codeproject example and that the byte array in ASCII spells "Ivan Medvedev" whom I assume to be the example author. Unfortunately I cannot change this.