Hmc Sha1 Hash - C# Producing Different Hash Output Than Ruby

HMC SHA1 hash - C# producing different hash output than Ruby

If I understand the code, it seems the Ruby code is hashing the key separately before feeding it to HMAC (which shoudln't be cryptographically necessary, as HMAC will hash a long key itself if necessary), and feeds the hashed key to HMAC together with the original message.

On the other hand, your C# code computes a HMAC with the original key and a hash of the message. (Inexplicably, the variables where you store the hashed message are called salt and private_key_binary, though the content is neither a salt nor a key...)

I cannot imagine that the Ruby and C# libraries would treat HMAC so differently that this is the right thing to do.

HMC SHA1 hash - Java producing different hash output than C#

I think the problem is in your .NET code. Does Configuration.RecurlySection.Current.PrivateKey return a string? Is that value the key you expect?

Using the following code, .NET and Java return identical results.

.NET Code

string message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
string privateKey = "0123456789ABCDEF0123456789ABCDEF";

var hashedKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(privateKey));
var hmac = new HMACSHA1(hashedKey);
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(message));

Console.WriteLine(" Message: {0}", message);
Console.WriteLine(" Key: {0}\n", privateKey);
Console.WriteLine("Key bytes: {0}", BitConverter.ToString(hashedKey).Replace("-", "").ToLower());
Console.WriteLine(" Result: {0}", BitConverter.ToString(hash).Replace("-", "").ToLower());

Result:


Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
Key: 0123456789ABCDEF0123456789ABCDEF

Key bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
Result: c8a9188dcf85d1378976729e50f1de5093fabb78

Java

String message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
String privateKey = "0123456789ABCDEF0123456789ABCDEF";

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes = md.digest(privateKey.getBytes("UTF-8"));

SecretKey sk = new SecretKeySpec(keyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(sk);
byte[] result = mac.doFinal(message.getBytes("ASCII"));

System.out.println(" Message: " + message);
System.out.println(" Key: " + privateKey + "\n");
System.out.println("Key Bytes: " + toHex(keyBytes));
System.out.println(" Results: " + toHex(result));

Result:


Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
Key: 0123456789ABCDEF0123456789ABCDEF

Key Bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
Results: c8a9188dcf85d1378976729e50f1de5093fabb78

HMC SHA1 hash - Java producing different hash output than C#

I think the problem is in your .NET code. Does Configuration.RecurlySection.Current.PrivateKey return a string? Is that value the key you expect?

Using the following code, .NET and Java return identical results.

.NET Code

string message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
string privateKey = "0123456789ABCDEF0123456789ABCDEF";

var hashedKey = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(privateKey));
var hmac = new HMACSHA1(hashedKey);
var hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(message));

Console.WriteLine(" Message: {0}", message);
Console.WriteLine(" Key: {0}\n", privateKey);
Console.WriteLine("Key bytes: {0}", BitConverter.ToString(hashedKey).Replace("-", "").ToLower());
Console.WriteLine(" Result: {0}", BitConverter.ToString(hash).Replace("-", "").ToLower());

Result:


Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
Key: 0123456789ABCDEF0123456789ABCDEF

Key bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
Result: c8a9188dcf85d1378976729e50f1de5093fabb78

Java

String message = "[1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]";
String privateKey = "0123456789ABCDEF0123456789ABCDEF";

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes = md.digest(privateKey.getBytes("UTF-8"));

SecretKey sk = new SecretKeySpec(keyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(sk);
byte[] result = mac.doFinal(message.getBytes("ASCII"));

System.out.println(" Message: " + message);
System.out.println(" Key: " + privateKey + "\n");
System.out.println("Key Bytes: " + toHex(keyBytes));
System.out.println(" Results: " + toHex(result));

Result:


Message: [1312701386,transactioncreate,[account_code:ABC,amount_in_cents:5000,currency:USD]]
Key: 0123456789ABCDEF0123456789ABCDEF

Key Bytes: 4d857d2408b00c3dd17f0c4ffcf15b97f1049867
Results: c8a9188dcf85d1378976729e50f1de5093fabb78

HMC SHA1 hash - C# producing different hash output than PHP

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.

Generating a SHA1 hash in Windows Phone outputs a different hash

In your example, you are Base64 encoding the byte array. Your correct output is in hexadecimal format, which you can achieve using:

return BitConverter.ToString(s.Hash).Replace("-", "");

instead of:

return Convert.ToBase64String(s.Hash);

How to do it in Ruby on rails

Not sure if it exactly the same, but it works for me:

@policy = ActiveSupport::Base64.encode64s(@policy)

# Sign policy with secret key
digest = OpenSSL::Digest::Digest.new('sha1')
@signature = ActiveSupport::Base64.encode64s(OpenSSL::HMAC.digest(digest, secretKey, @policy))


Related Topics



Leave a reply



Submit