2016-08-26 52 views
0

我試圖做一個Twitter的權威性和Django中間件的幫助下,我在那裏計算這樣的請求的簽名(https://dev.twitter.com/oauth/overview/creating-signatures):Python的HMAC散列值編碼爲base64

key = b"MY_KEY&" 
    raw_init = "POST" + "&" + quote("https://api.twitter.com/1.1/oauth/request_token", safe='') 

    raw_params = <some_params> 
    raw_params = quote(raw_params, safe='') 

    #byte encoding for HMAC, otherwise it returns "expected bytes or bytearray, but got 'str'" 
    raw_final = bytes(raw_init + "&" + raw_params, encoding='utf-8') 

    hashed = hmac.new(key, raw_final, sha1) 

    request.raw_final = hashed 

    # here are my problems: I need a base64 encoded string, but get the error "'bytes' object has no attribute 'encode'" 
    request.auth_header = hashed.digest().encode("base64").rstrip('\n') 

正如你所看到的,沒有辦法base64編碼一個'字節'對象。

提出的解決方案在這裏:Implementaion HMAC-SHA1 in python

+0

你試過了:'base64.encodestring(str(raw_final))'? –

+0

@ Jean-FrançoisFabre我爲什麼要編碼raw_final?我需要一個HMAC對象轉換爲base64字符串...所有這些根據twitter文檔 - https://dev.twitter.com/oauth/overview/creating-signatures在頁面的最底部 –

回答

1

訣竅是用base64模塊,而不是直接的STR /字節編碼,它支持二進制。

你可以這樣適合它(未經測試你的背景下,應工作):

import base64 
#byte encoding for HMAC, otherwise it returns "expected bytes or bytearray, but got 'str'" 
raw_final = bytes(raw_init + "&" + raw_params, encoding='utf-8') 

hashed = hmac.new(key, raw_final, sha1) 

request.raw_final = hashed 

# here directly use base64 module, and since it returns bytes, just decode it 
request.auth_header = base64.b64encode(hashed.digest()).decode() 

出於測試目的,找到一個獨立的下面,工作示例(Python 3兼容,巨蟒2.x的用戶都創建bytes字符串時刪除 「ASCII」 參數):

from hashlib import sha1 
import hmac 
import base64 

# key = CONSUMER_SECRET& #If you dont have a token yet 
key = bytes("CONSUMER_SECRET&TOKEN_SECRET","ascii") 


# The Base String as specified here: 
raw = bytes("BASE_STRING","ascii") # as specified by oauth 

hashed = hmac.new(key, raw, sha1) 

print(base64.b64encode(hashed.digest()).decode()) 

結果:

Rh3xUffks487KzXXTc3n7+Hna6o= 

PS:您所提供的答案已經不只有Python 3下它的蟒蛇2工作。

+0

非常感謝!這真的很好 –