Python的HMAC散列值编码为base64
问题描述:
我试图做一个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
答
诀窍是用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
非常感谢!这真的很好 –
你试过了:'base64.encodestring(str(raw_final))'? –
@ Jean-FrançoisFabre我为什么要编码raw_final?我需要一个HMAC对象转换为base64字符串...所有这些根据twitter文档 - https://dev.twitter.com/oauth/overview/creating-signatures在页面的最底部 –