1

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?

4
  • 2
    It looks like the example includes some spaces or tabs, and ends with \r\n, which your code doesn't. Commented Mar 5, 2018 at 0:58
  • My code starts with the same base 64 encoded string as does the example. My example has Console.WriteLine(data64) and this output matches the example up to this point. It seems to be the use of this string with the SHA384 hashing algorithm that is wrong somehow. Commented Mar 5, 2018 at 1:01
  • 2
    The code you posted hashes a different string than the example you posted, the whitespace is different. Whitespace is significant in SHA384. Commented Mar 5, 2018 at 1:03
  • @DourHighArch Nevermind - you're right. The whitespace differs and actually checking that the base64s match in code rather than by eye makes a big difference. Thanks! However, the output still doesn't match. I've edited the question to reflect the additional newline at the end of the braces. Commented Mar 5, 2018 at 1:12

1 Answer 1

2

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);
Sign up to request clarification or add additional context in comments.

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.