Question

I have a code in PHP and that is below when i Execute the Below PHP code and when i Run the C# code which is below PHP Code i got different Result I dont know where I am wrong.

$accessID = "member-1681fca809";
$secretKey = "63f22236ab43b69462b3272b110e3c78";

$expires = 1357039353;
$stringToSign = $accessID."\n".$expires;

$binarySignature = hash_hmac('sha1', $stringToSign, $secretKey, true);
$urlSafeSignature = urlencode(base64_encode($binarySignature));
print_r($expires);
print_r($urlSafeSignature);

I got Output
1357039353
M1PZW2DYVzdRV1l4ZHBPAmiv9iM%3D

While I run same code in c# i got different Output

string accessid = "member-1681fca809";
string secretekey = "63f22236ab43b69462b3272b110e3c78";
int Expire = 1357039353;

string stringTosign = accessid + Environment.NewLine + Expire;
byte[] secret = UTF8Encoding.UTF8.GetBytes(secretekey);

HMACSHA1 myhmacsha1 = new HMACSHA1(secret);
byte[] byteArray = Encoding.ASCII.GetBytes(stringTosign);
MemoryStream stream = new MemoryStream(byteArray);
byte[] hashValue = myhmacsha1.ComputeHash(stream);
string k = Convert.ToBase64String(Encoding.ASCII.GetBytes(hashValue.ToString()));

console.WriteLine(Expire);
console.WriteLine(k);

I Got OutPut
1357039353
U3lzdGVtLkJ5dGVbXQ==
Was it helpful?

Solution

Modified your code a bit.

string accessid = "member-1681fca809";
string secretekey = "63f22236ab43b69462b3272b110e3c78";
int Expire = 1357039353;

string stringTosign = accessid + "\n" + Expire;
byte[] secret = UTF8Encoding.UTF8.GetBytes(secretekey);

HMACSHA1 myhmacsha1 = new HMACSHA1(secret);
byte[] byteArray = Encoding.ASCII.GetBytes(stringTosign);
MemoryStream stream = new MemoryStream(byteArray);
byte[] hashValue = myhmacsha1.ComputeHash(stream);
string k = Convert.ToBase64String(hashValue);

Console.WriteLine(Expire);
Console.WriteLine(k);

The only difference will be the last character since you are using url_encode which will convert the "=" character.

OTHER TIPS

Thanks! Problem solved,still wanted to share my experience.

The mistake I was doing is that i used string builder sbr.Append instead of sbr.AppendLine() or direct string concatenation like you did where \n is read as new line.

When you are getting different results for HMACSHA1/hash_hmac('sha1', ...) start split-testing the PHP and the C# versions with really simple inputs like input = "a", key = "b". If you are encoding the key before passing it to the HMACSHA1 check that you are encoding it correctly. I spent hours thinking the problem was HMACSHA1 hashing when in reality it was a bad implementation of pack('H*'...).

public static string Encode(string input, byte[] key)
{
    HMACSHA1 myhmacsha1 = new HMACSHA1(key);
    byte[] byteArray = Encoding.ASCII.GetBytes(input);
    MemoryStream stream = new MemoryStream(byteArray);
    return myhmacsha1.ComputeHash(stream).Aggregate("", (s, e) => s + String.Format("{0:x2}", e), s => s);
}

and pack('H*'...) C# implementation:

public static byte[] PackH(string hex)
{
    if ((hex.Length % 2) == 1) hex += '0';
    byte[] bytes = new byte[hex.Length / 2];
    for (int i = 0; i < hex.Length; i += 2)
    {
        bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
    }
    return bytes;
}

DO NOT convert things from byte array to string and back to byte array when you are passing stuff to the Encode function, just pass a byte[] & keep things simple.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top