Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert C# hashing function into PHP

Tags:

c#

php

hmac

I have the following function in C#, a hashing function which I need converted into PHP. I've tried a few things in PHP but I don't get the same results (I'm not at all good with .NET)

private static string GetSignature(string args, string privatekey)
{
    var encoding = new System.Text.ASCIIEncoding();
    byte[] key = encoding.GetBytes(privatekey);
    var myhmacsha256 = new HMACSHA256(key);
    byte[] hashValue = myhmacsha256.ComputeHash(encoding.GetBytes(args));
    string hmac64 = Convert.ToBase64String(hashValue);
    myhmacsha256.Clear();
    return hmac64;
} 

One (wrong) attempt in PHP is this:

function encode($data,$key)
{
    return base64_encode( hash_hmac('sha256', $data, $key ) );
}

The ANSWER

A slight variation of what was suggested below by DampeS8N worked for me.

function encode($data,$key)
{
    iconv_set_encoding("input_encoding", "ASCII");
    iconv_set_encoding("internal_encoding", "ASCII");
    iconv_set_encoding("output_encoding", "ASCII");

    return base64_encode( hash_hmac('sha256', $data, $key, true ) );
}

Please also not the fourth parameter of hash_hmac - now set to true for raw output as binary data

like image 216
32423hjh32423 Avatar asked Jan 09 '12 10:01

32423hjh32423


People also ask

What does C equal in Fahrenheit?

C° to F°: Celsius to Fahrenheit Conversion Formula To convert temperatures in degrees Celsius to Fahrenheit, multiply by 1.8 (or 9/5) and add 32.

What does C mean in conversion?

Quick Celsius (°C) / Fahrenheit (°F) Conversion:°C.


1 Answers

I suspect the very first line of your .net code is the culprit. PHP has no encoding for the string itself and so when it comes time to hash it either is hashing the internal PHP string format's bytes (unlikely, can someone else confirm?) or more than likely is converting to something else first. In this case probably unicode which is decidedly not the same bytes that the string would be in ASCII as .net is requesting.

My advice would be to ensure that PHP is also using ASCII, with iconv, to allow interoperability.

function encode($data,$key)
{
    return base64_encode( hash_hmac('sha256', iconv( iconv_get_encoding( "internal_encoding"), "ASCII", $data ), iconv( iconv_get_encoding( "internal_encoding"), "ASCII", $key ) ) );
}

I can't be sure that the above code will output the desired hashes, however, as I don't have .net handy to test the initial code. But this might point you in the right direction.

If this doesn't work, the value inside iconv_get_encoding( might be the culprit, try "output_encoding" or "input_encoding" as well. It is also possible that you'll need to set these same values to ASCII with iconv_set_encoding(.

Good Luck!


Update! This is what ultimately worked:

function encode($data,$key)
{
    iconv_set_encoding("input_encoding", "ASCII");
    iconv_set_encoding("internal_encoding", "ASCII");
    iconv_set_encoding("output_encoding", "ASCII");

    return base64_encode( hash_hmac('sha256', $data, $key, true ) );
}
like image 51
DampeS8N Avatar answered Oct 05 '22 14:10

DampeS8N