1

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==
4
  • 2
    Why are you converting the byte[] hashValue to a byteArray again? Commented Jan 1, 2013 at 12:11
  • U3lzdGVtLkJ5dGVbXQ== decodes to System.Byte[] Commented Jan 1, 2013 at 12:12
  • Dont use Environment.NewLine it could be \r\n! Commented Jan 1, 2013 at 12:12
  • Did you want Encoding.ASCII (7-bit character representation according to msdn.microsoft.com/en-us/library/…)? Start with fixed values, such as the string "foo" and calculate the HMACSHA1 on each system. If they are the same, the issue is wither your concatenation or encoding. Otherwise, it is probably padding. Commented Jan 1, 2013 at 12:17

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.