samedi 11 juin 2016

Unicode Objects must be encoded before hashing error


Questions dealing with similar issues: SO 1, SO 2, SO 3.

I've tried their answers, encoding pretty much any string to utf-8, but hmac still tells me to encode my unicoe chars. The biggest problem is that I can't even identify the offending variable; print outputs tell me they're either strings or bytes; in the case of the former I attach .encode(), but that hasn't helped.

I'm trying to query the GDAX API and am also using the code as given on their API page. Being written for Python2.7, I figured there might be issues with encoding and all, but this is just not making sense to me.

My code:

class CoinbaseExchangeAuth(AuthBase):
    def __init__(self, api_key, secret_key, passphrase):
        self.api_key = api_key.encode()
        self.secret_key = secret_key.encode()
        self.passphrase = passphrase.encode()

    def __call__(self, request):
        timestamp = str(time.time())
        message = timestamp + request.method + request.path_url + (request.body or '')
        hmac_key = base64.b64decode(self.secret_key)
    #print(hmac_key, type(hmac_key))
    #print(message, type(message))
    signature = hmac.new(hmac_key, message, hashlib.sha256)

    signature_b64 = signature.digest().encode('base64').rstrip('n')


    request.headers.update({
        'CB-ACCESS-SIGN': signature_b64,
        'CB-ACCESS-TIMESTAMP': timestamp,
        'CB-ACCESS-KEY': self.api_key,
        'CB-ACCESS-PASSPHRASE': self.passphrase,
        'Content-Type': 'application/json'
    })
    return request

The error:

File "F:gitknowherePrivatebitex-crawlergdax_clientgdaxexapi.py", line 47, in __call__
signature = hmac.new(hmac_key, message, hashlib.sha256)
File "C:UsersnlsAnaconda3libhmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "C:UsersnlsAnaconda3libhmac.py", line 84, in __init__
self.update(msg)
File "C:UsersnlsAnaconda3libhmac.py", line 93, in update
self.inner.update(msg)
TypeError: Unicode-objects must be encoded before hashing

When I type check the objects I feed to my hmac.new() call, it tells me I have a str object and a bytes object.

print(type(hmac_key)) # <bytes>
print(type(message))  # <str>

Naturally, I thought I need to encode that sucker too:

signature = hmac.new(hmac_key, message.encode(), hashlib.sha256)

which resulted in an error on this line:

signature_b64 = signature.digest().encode('base64').rstrip('n')

namely:

File "F:/git/knowhere/Private/bitex-crawler/gdax_client/client.py",
[..]
File "F:gitknowherePrivatebitex-crawlergdax_clientgdaxexapi.py", line 123, in _query
r = api_query(url, json=req, auth=auth)
File "C:UsersnlsAnaconda3libsite-packagesrequestsapi.py", line 67, in get
return request('get', url, params=params, **kwargs)
File "C:UsersnlsAnaconda3libsite-packagesrequestsapi.py", line 53, in request
return session.request(method=method, url=url, **kwargs)
File "C:UsersnlsAnaconda3libsite-packagesrequestssessions.py", line 454, in request
prep = self.prepare_request(req)
File "C:UsersnlsAnaconda3libsite-packagesrequestssessions.py", line 388, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:UsersnlsAnaconda3libsite-packagesrequestsmodels.py", line 297, in prepare
self.prepare_auth(auth, url)
File "C:UsersnlsAnaconda3libsite-packagesrequestsmodels.py", line 490, in prepare_auth
r = auth(self)
File "F:gitknowherePrivatebitex-crawlergdax_clientgdaxexapi.py", line 49, in __call__
signature_b64 = signature.digest().encode('base64').rstrip('n')
AttributeError: 'bytes' object has no attribute 'encode'

..So I can't have unencoded unicode objects, but I cant have bytes later on either? How on earth do I fix this? Appreciating any help on this, because I'm profoundly confused.


Aucun commentaire:

Enregistrer un commentaire