【问题标题】:Python HMAC hashed value encoding to base64Python HMAC散列值编码为base64
【发布时间】:2017-01-02 22:47:03
【问题描述】:

我正在尝试在 django 中间件的帮助下进行 twitter 身份验证,我在其中计算这样的请求的签名 (https://dev.twitter.com/oauth/overview/creating-signatures):

    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.encodestring(str(raw_final))
  • @Jean-FrançoisFabre 为什么我要编码 raw_final?我需要一个 HMAC 对象转换为 base64 字符串...所有这些都根据 twitter 文档 - dev.twitter.com/oauth/overview/creating-signatures 在页面的最底部

标签: python django twitter base64 hmacsha1


【解决方案1】:

诀窍是直接使用base64模块,而不是支持二进制的str/byte编码。

你可以这样适应它(在你的上下文中未经测试,应该可以工作):

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 兼容,Python 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。它仅适用于 python 2。

【讨论】:

    【解决方案2】:

    只是想我会调整Python3 的答案。

    from hashlib import sha512
    import hmac
    import base64
    
    
    key = b"KEY"
    path = b"WHAT YOU WANT TO BE SIGNED"
    
    hashed = hmac.new(key, path, sha512).digest()
    
    print(base64.b64encode(hashed))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      相关资源
      最近更新 更多