Reputation: 1339
I'm trying to consume an API and for that purpose I have to create a signature using SHA384. The docs describe doing:
signature = hex(HMAC_SHA384(base64(payload), key=api_secret))
They give an example:
~$ base64 << EOF
> {
> "request": "/v1/order/status",
> "nonce": 123456,
>
> "order_id": 18834
> }
> EOF
ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYs
CgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=
In this example, the api_secret is 1234abcd
echo -n 'ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=' | openssl sha384 -hmac "1234abcd"
(stdin)= 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f
It took a little while, but I realized that in order to replicate the base64 of the original string I had to replace "\r\n" with "\n".
Here's what I've got (ignoring the formatting that I wasted 20 minutes trying to make good):
var raw = @"{
""request"": ""/v1/order/status"",
""nonce"": 123456,
""order_id"": 18834
}
";
var data = raw.Replace("\r\n", "\n");
Console.WriteLine(data);
var data64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(data.ToCharArray()));
if (data64 != "ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=")
{
Console.WriteLine("base64's don't match");
}
Console.WriteLine("ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=");
Console.WriteLine(data64);
var key = Encoding.UTF8.GetBytes("1234abcd");
using (var hash = new HMACSHA384(key))
{
var hash64 = Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(data64)));
StringBuilder sb = new StringBuilder();
foreach (char c in hash64)
{
sb.Append(Convert.ToInt32(c).ToString("x"));
}
Console.WriteLine(sb.ToString());
// yields:
// 4d337a49744f70704c50356c744b68667a4a38454b79342f6343724a5676304a6a57414b7356634664314158767135414b2b647a7a753451635a2f3344584550
// should be:
// 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f
}
My code's output doesn't match the documentation's expected output. Can someone see what I'm doing wrong?
Upvotes: 1
Views: 225
Reputation: 101443
For some reason you are converting hash to base-64 string, then you convert each character of that string to int and that you convert to hex. All that is not needed and not described in "documentation". Instead, do like this:
var hashBin = hash.ComputeHash(Encoding.UTF8.GetBytes(data64));
var hashHex = BitConverter.ToString(hashBin).Replace("-", "").ToLowerInvariant();
Console.WriteLine(hashHex);
Upvotes: 2