Search code examples
pythonpython-3.xhmac

Generate HMAC SHA256 signature Python


Trying to generate HMAC SHA256 signature for 3Commas, I use the same parameters from the official example, it should generate: "30f678a157230290e00475cfffccbc92ae3659d94c145a2c0e9d0fa28f41c11a"

But I generate: "17a656c7df48fa2db615bfc719627fc94e59265e6af18cc7714694ea5b58a11a"

Here is what I tried:

secretkey = 'NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j'
totalParams = '/public/api/ver1/accounts/new?type=binance&name=binance_account&api_key=XXXXXX&secret=YYYYYY'
print 'signature = '+hashlib.sha256((secretkey+totalParams).encode('ASCII')).hexdigest()

Can anyone help me out?


Solution

  • Try using the hmac module instead of the hashlib module:

    import hmac
    import hashlib
    
    
    secret_key = b"NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
    total_params = b"/public/api/ver1/accounts/new?type=binance&name=binance_account&api_key=XXXXXX&secret=YYYYYY"
    signature = hmac.new(secret_key, total_params, hashlib.sha256).hexdigest()
    print("signature = {0}".format(signature))
    

    This gives the desired result:

    signature = 30f678a157230290e00475cfffccbc92ae3659d94c145a2c0e9d0fa28f41c11a
    

    Edit

    Note that the hmac module accepts bytes for the key and message. If your inputs are strings, you can use the str.encode() method with the relevant character set, e.g. 'ascii', 'utf-8' (default), etc.

    In the above code example I am using the bytes literal introduced in PEP-3112. A bytes literal can only contain ASCII characters, anything outside of the range of ASCII must be entered as the relevant escape sequences.

    For example:

    emoji = b'\xf0\x9f\x98\x84'
    print(emoji.decode('utf-8'))
    

    Therefore, the following line from the code example above...

    secret_key = b"NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j"
    

    ...is equivalent to:

    secret_key = "NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j".encode('ascii')