How To Create A Hash That Can Be Read In PHP And C#?

960 views Asked by At

The project in question is a simple REST interface over HTTPS. I'm trying to hash the data being passed so I can make sure it hasn't been modified during transport (using a salt, of course). However, there seems to be something wrong with my code. The REST server is PHP, and the client is C#.

PHP

public function hash($text)
{
    $text = utf8_encode($text);
    $encrypted = hash("sha512", $text);
    return base64_encode($encrypted);
}

C#

public static string Hash(string Plaintext)
{
    byte[] HashValue, MessageBytes = Encoding.UTF8.GetBytes(Plaintext);

    SHA512Managed SHhash = new SHA512Managed();

    HashValue = SHhash.ComputeHash(MessageBytes);

    return Convert.ToBase64String(HashValue);
}

These do not produce the same hash. What am I doing wrong?

1

There are 1 answers

1
Servy On

As per this edit by the OP, this is the solution:

First, hash in PHP returns hexadecimal by default, whereas C# returns the raw data. Ended up needing to change hash("sha512", $text) to hash("sha512", $text, true). Secondly, utf8_encode doesn't appear to do the same thing as C#'s Encoding.UTF8.GetBytes; when I switched utf8_encode($text) to mb_convert_encoding($text, 'UTF-16LE') and Encoding.UTF8.GetBytes to new UnicodeEncoding().GetBytes, the hashes began to match up.

In short, the final working code is:

PHP

public function hash($text)
{
    $text = mb_convert_encoding($text, 'UTF-16LE');
    $encrypted = hash("sha512", $text, true);
    return base64_encode($encrypted);
}

C#

public static string Hash(string Plaintext)
{
    byte[] HashValue, MessageBytes = new UnicodeEncoding().GetBytes(Plaintext);

    SHA512Managed SHhash = new SHA512Managed();

    HashValue = SHhash.ComputeHash(MessageBytes);

    return Convert.ToBase64String(HashValue);
}