2
$\begingroup$

This question already has an answer here:

I am trying to authenticate a http request using Mathematica, but i keep getting "Authentication failed" responses.

I think the problem is that the Hmac SHA512 I generate is 128 characters long, and the one shown in an example demonstrating how the API works (https://github.com/BTCMarkets/API/wiki/Authentication) is 88 long.

The Hmac SHA512 function I am using was found here on stackexchange (modified it slightly to include StringRepeat and StringRightPad, since Mathematica 9 does not have these functions inbuilt) and it gives the same responses that online Hmac SHA512 generators give. The code is shown below

HmacSHA512[message_, key_] :=
  Module[
   {blocksize = 128, dkey, ipad, opad},
   StringRepeat[string_, n_] :=
    StringJoin[
     ConstantArray[string, n]
     ];
   StringPadRight[string_, n_, padding_] :=
    StringJoin[
     Join[
      {string},
      ConstantArray[
       padding,
       n - StringLength[string]
       ]
      ]
     ];
   dkey =
    If[
     StringLength[key] <= blocksize,
     StringPadRight[key, blocksize, FromCharacterCode[0]],
     IntegerString[Hash[key, "SHA512"], 16]
     ];
   {ipad, opad} =
    Map[
     FromCharacterCode[
       BitXor[
        ToCharacterCode[
         StringRepeat[
          FromCharacterCode[
           FromDigits[#, 16]
           ],
          blocksize
          ]
         ],
        ToCharacterCode[dkey]
        ]
       ] &,
     {"36", "5c"}
     ];
   IntegerString[
    Hash[
     StringJoin[
      opad,
      ExportString[
       IntegerDigits[
        Hash[
         StringJoin[ipad, message],
         "SHA512"
         ],
256
        ],
       "Binary"
       ]
      ],
     "SHA512"
     ],
16
    ]
   ];

Anyone know how to modify this function so that it gives results that are 88 characters long rather than 128?

$\endgroup$

marked as duplicate by ilian, Coolwater, MarcoB, Sektor, LCarvalho Jan 4 '18 at 16:33

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ Hmm, it only made it longer ;_; Now its 172 characters in length. Nuuuuuuu~ >_< $\endgroup$ – user12572 Dec 30 '17 at 7:00
  • $\begingroup$ Here is a web page I found that i think is related to my problem (jokecamp.com/blog/…). Here, using "Message" and "secret" they generate a Hmac SHA256 of "qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc=" (44 characters long) when other online Hmac SHA256 generators give "aa747c502a898200f9e4fa21bac68136f886a0e27aec70ba06daf2e2a5cb5597" (64 characters long). Is it because they are calculating a simplified Hmac SHA256 string? $\endgroup$ – user12572 Dec 30 '17 at 7:44
  • 1
    $\begingroup$ Actually this is the same issue as your previous question: the Base64 encoding needs to be done on the 64-byte result of HmacSHA512, not on the 128 bytes of its representation as a hexadecimal string. $\endgroup$ – ilian Dec 30 '17 at 14:15
  • $\begingroup$ Thanks. My bad. i never done anything related to cryptography before so I don't really understand it $\endgroup$ – user12572 Dec 30 '17 at 16:24
3
$\begingroup$

Ahh, I figured it out! Thanks for your help, and thanks to the person who helped me with my last question (Want to convert a string to a SHA512 Base64 value), cause that also helped me find the solution.

You were right, it needed to be encoded to Base-64. The new function for this is given below:

HmacSHA512Base64[message_, key_] :=
  Module[
   {blocksize = 128, dkey, ipad, opad},
   StringRepeat[string_, n_] :=
    StringJoin[
     ConstantArray[string, n]
     ];
   StringPadRight[string_, n_, padding_] :=
    StringJoin[
     Join[
      {string},
      ConstantArray[
       padding,
       n - StringLength[string]
       ]
      ]
     ];
   dkey =
    If[
     StringLength[key] <= blocksize,
     StringPadRight[key, blocksize, FromCharacterCode[0]],
     IntegerString[Hash[key, "SHA512"], 16]
     ];
   {ipad, opad} =
    Map[
     FromCharacterCode[
       BitXor[
        ToCharacterCode[
         StringRepeat[
          FromCharacterCode[
           FromDigits[#, 16]
           ],
          blocksize
          ]
         ],
        ToCharacterCode[dkey]
        ]
       ] &,
     {"36", "5c"}
     ];
   Developer`EncodeBase64[
    FromCharacterCode[
     IntegerDigits[
      Hash[
       StringJoin[
        opad,
        ExportString[
         IntegerDigits[
          Hash[
           StringJoin[ipad, message],
           "SHA512"
           ],
256
          ],
         "Binary"
         ]
        ],
       "SHA512"
       ],
256
      ]
     ]
    ]
   ];

Using input "Message" and key "secret" yields

"z12KOCXYQjCZyKf6WP+yYBONCS+IwNuv9oPbRcL4u+WetE4BvAm1Ysy+bEyGxq/QDLAufO0sPnVLUl/ubvPGdQ==" (88 characters in length)

And this is result is confirmed on this site:

https://www.liavaag.org/English/SHA-Generator/HMAC/

:3

Thanks again!

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.