BitMEX / sample-market-maker

Sample BitMEX Market Making Bot
Apache License 2.0
1.7k stars 758 forks source link

Hmac signature incorrect in Ruby and Python when % symbol is in url #149

Open PeterJahnes opened 6 years ago

PeterJahnes commented 6 years ago

I am building a app that uses both your Websocket and HTTP APIs. I can authenticate fine using the WS and with some HTTP requests. When I try your examples for generating the signature on this page https://www.bitmex.com/app/apiKeysUsage the first and the third examples produce matching signatures but the second example returns a different value for me. I have generated the signature in ruby 2.5.1, python2.7, and python3. all 3 give the same incorrect result for the middle example but correct results for the first and third. When I try to authenticate a message that contains a % sign it does not work properly. Any help would be great. I copied the python code directly from the Market-Maker app. Cheers

tosign = bytes('GET/api/v1/instrument?filter=%7B%22symbol%22%3A+%22XBTM15%22%7D1518064237','utf8') sig = bytes('chNOOS4KvNXR_Xq4k4c9qsfoKWvnDecLATCRlcBwyKDYnWgO','utf-8') h = hmac.new( sig, tosign, hashlib.sha256 ) print( h.hexdigest() ) e2f422547eecb5b3cb29ade2127e21b858b235b386bfa45e1c1756eb3383919f ^^ wrong answer ^^ e547ec6fe8720c3a256203dd0f2bd82ce591d0d9766a442074d5190efd2687c7 ^^ correct answer ^^

UPDATE : I am using KDE NEON which is upstream from ubuntu 16.04. Amd and Intel chips are both producing this issue I have now gotten the SAME incorrect result using openssl in bash as well as the previous ruby 2.5.1, python2.7, and python3. I have tried every encoding known to transcode from UTF-8. (99 different encodings) most produce the same incorrect result, some produce different incorrect results. I have tried padding the api-secret as it is not the full 64 char that it can be and hmac pads if not. I have tried clipping the string to encode to 64 chars as hmac may do this too. I have looked into the maths and CS of how hmacs are generated and can not for the life of me figure out what you are doing. I have tried all sorts of modified strings that maybe you were doing and mistakenly wrote something out like in the first example. I wish this was just a case of the example being incorrect but that is not the case. If I use a % symbol in any url request it returns signature invalid, if there is no % symbol in the string to encode, the request goes through flawlessly

ryanfox commented 5 years ago

Are you maybe double-urlencoding something? I just ran all 3 examples from https://www.bitmex.com/app/apiKeysUsage through market_maker.auth.APIKeyAuth.generate_signature and all 3 match the listed signature in the docs.