2016-06-11 43 views
3

Fragen zu ähnlichen Problemen: SO 1, SO 2, SO 3.Unicode-Objekte müssen vor dem Hashing-Fehler codiert werden

Ich habe ihre Antworten versucht, Codierung so ziemlich jede Zeichenfolge utf-8, aber hmac sagt mir immer noch, meine Unicode-Zeichen zu kodieren. Das größte Problem ist, dass ich nicht einmal die beleidigende Variable identifizieren kann; Druckausgaben sagen mir, dass sie entweder strings oder bytes sind; im Falle der ehemaligen ich anfügen .encode(), aber das hat nicht geholfen.

Ich versuche, die GDAX API abzufragen und bin auch using the code as given on their API page. Da ich für Python2.7 geschrieben habe, dachte ich, es könnte Probleme mit der Kodierung und allem geben, aber das macht einfach keinen Sinn für mich.

Mein 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 

Der Fehler:

File "F:\git\knowhere\Private\bitex-crawler\gdax_client\gdaxex\api.py", line 47, in __call__ 
signature = hmac.new(hmac_key, message, hashlib.sha256) 
File "C:\Users\nls\Anaconda3\lib\hmac.py", line 144, in new 
return HMAC(key, msg, digestmod) 
File "C:\Users\nls\Anaconda3\lib\hmac.py", line 84, in __init__ 
self.update(msg) 
File "C:\Users\nls\Anaconda3\lib\hmac.py", line 93, in update 
self.inner.update(msg) 
TypeError: Unicode-objects must be encoded before hashing 

Wenn ich die Objekte des Typs überprüfen ich meinen hmac.new() Anruf füttern, es sagt mir, ich habe ein str Objekt und ein bytes Objekt.

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

Natürlich, ich dachte, ich brauche zu diesen Sauger zu kodieren:

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

, die auf dieser Linie in einem Fehler:

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

nämlich:

File "F:/git/knowhere/Private/bitex-crawler/gdax_client/client.py", 
[..] 
File "F:\git\knowhere\Private\bitex-crawler\gdax_client\gdaxex\api.py", line 123, in _query 
r = api_query(url, json=req, auth=auth) 
File "C:\Users\nls\Anaconda3\lib\site-packages\requests\api.py", line 67, in get 
return request('get', url, params=params, **kwargs) 
File "C:\Users\nls\Anaconda3\lib\site-packages\requests\api.py", line 53, in request 
return session.request(method=method, url=url, **kwargs) 
File "C:\Users\nls\Anaconda3\lib\site-packages\requests\sessions.py", line 454, in request 
prep = self.prepare_request(req) 
File "C:\Users\nls\Anaconda3\lib\site-packages\requests\sessions.py", line 388, in prepare_request 
hooks=merge_hooks(request.hooks, self.hooks), 
File "C:\Users\nls\Anaconda3\lib\site-packages\requests\models.py", line 297, in prepare 
self.prepare_auth(auth, url) 
File "C:\Users\nls\Anaconda3\lib\site-packages\requests\models.py", line 490, in prepare_auth 
r = auth(self) 
File "F:\git\knowhere\Private\bitex-crawler\gdax_client\gdaxex\api.py", line 49, in __call__ 
signature_b64 = signature.digest().encode('base64').rstrip('\n') 
AttributeError: 'bytes' object has no attribute 'encode' 

..So kann ich nicht Unicode ob Ja, aber ich kann später auch keine Bytes mehr haben? Wie in aller Welt repariere ich das? Ich schätze jede Hilfe, weil ich zutiefst verwirrt bin.

+1

Sieht aus wie Sie verwenden Python-2-only-Bibliotheken mit Python 3. Wenn es keine Version Python 3 ist, können Sie in den Hafen haben, den Dritten Code selbst (oder wechseln Sie zu Python 2.7) sollten In diesem Handbuch wird erklärt, warum Sie bekomme diese Fehler und wie sie gelöst werden können. https://docs.python.org/3/howto/pyporting.html#text-versus-binary-data –

+0

Prost, Mann! Daran habe ich nicht gedacht! – nlsdfnbch

Antwort

3

"Parameter msg can be of any type supported by hashlib.".

"Note: Feeding string objects into is not supported, as hashes work on bytes, not on characters.".

Daher muss Ihre Nachricht vom Typ bytes sein. Verwenden Sie .encode() für die Nachricht, die Ihnen das Byte-Objekt geben wird.

Hinweis: Dies ist nur für Python 3 notwendig!

Um den Digest nach Base64 zu codieren, verwenden Sie base64 library.

import base64 
signature_b64 = base64.b64encode(signature.digest()) 
+0

Hab nicht gesehen, dass du das schon probiert hast. Bearbeiten .... –

+0

alles gut! Ich war code-blind, Codierung mit 'base64' funktioniert jetzt gut. Ich habe in den letzten zwei Tagen sechs dieser Conversions geschrieben, manchmal ist das alles ein bisschen eine Importzusammenfassung. – nlsdfnbch