Fox Alex Fox Alex - 6 months ago 85
PHP Question

Converting C# code to php encoding issue

I try to replicate this C# code in php to get the same output(I cannot change c# code only php).And here I'm stuck

public static string HashData(string textToBeEncripted)
{
//Convert the string to a byte array
Byte[] byteDataToHash = System.Text.Encoding.Unicode.GetBytes(textToBeEncripted);

//Compute the MD5 hash algorithm
Byte[] byteHashValue = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(byteDataToHash);

return System.Text.Encoding.Unicode.GetString(byteHashValue);
}


The php code that I have made till now looks like this

$a = "test";
$a = mb_convert_encoding($a, "UTF-16LE");

$a = md5($a,true);

$a = unpack('C*', $a);
var_dump($a);
//with the output
array(16) { [1]=> int(200) [2]=> int(5) [3]=> int(158) [4]=> int(46) [5]=> int(199) [6]=> int(65) [7]=> int(159) [8]=> int(89) [9]=> int(14) [10]=> int(121) [11]=> int(215) [12]=> int(241) [13]=> int(183) [14]=> int(116) [15]=> int(191) [16]=> int(230) }


As you can see the output is the same as in the C# code
But I'm stuck at the function System.Text.Encoding.Unicode.GetString().How to replicate this in php?Or there is a easier way to get the same output?(I cannot change the C# code sorry)


Edit: Based on Vasiliy Zverev answers since the php hash is different a little bit.I end up making aproximating the hash value of php with the C# hash

function validare_parola($parola,$dbHash){

$parola = mb_convert_encoding($parola, "UTF-16LE");
$parola = md5($parola, true);
$parola = mb_convert_encoding($parola, "UCS-2BE", "UCS-2LE");
$parola = bin2hex($parola);

$procent;
similar_text($dbHash,$parola,$procent);

if($procent>=90){
return true;
}else{
return false;
}

}

$parola = "testa";

$dbHash = "10095018710be2bcbbf9bba3f9d91ce8";
if(validare_parola($parola,$dbHash)){
echo 'PASSWORD CORRECT.You can log in.';
}else{
echo 'INCORRECT PASSWORD.Try again.';
}


As a side note don't use md5 for passwords use php password hashing api

Answer

The solution:

$a = "test";
$a = mb_convert_encoding($a, "UTF-16LE");
$a = md5($a, true);
$a_orig = $a; 
$a = mb_convert_encoding($a, "UTF-16LE","UTF-16LE"); // find invalid UTF-16 characters
// System.Text.Encoding.Unicode.GetString(byteHashValue) replaces invalid characters to 0xfffd ('я') while PHP to 0x003d ('?')
// so replace them like C# does 
for($i=0; $i<16; $i+=2) {
    if($a[$i]!=$a_orig[$i]) { 
        $a[$i] = chr(0xfd);
        $a[$i+1] = chr(0xff);
    }
}
$a = mb_convert_encoding($a, "byte2be", "byte2le");
$a = bin2hex($a);
$a = ltrim($a, '0');
echo($a);
Comments