Python 3 - hmac 的 ascii 到十六进制

Python 3 - ascii to hex for hmac

我遇到了问题,不太确定如何解释,但我会尽力而为。

所以我正在尝试使用 API 进行身份验证,这需要获取网站以十六进制表示形式提供的私钥(例如,示例令牌是“665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569”)并解码为 ascii 以创建一个键控哈希,所以我可以在身份验证过程的一部分 http header 中传递它。

说到python2我可以简单的

import hashlib
import hmac
import requests


headers = {
           "custom header": hmac.new("665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569".decode("hex"),
                                     msg="whatever",
                                     digestmod=hashlib.sha256).hexdigest()
          }
requests.get("my url", headers=headers)

然而,尽管谷歌搜索了几个小时,各种 SO 帖子并查看了 hmac 的官方文档,我还是无法在 python3 中使用它。

这似乎源于 python2 和 3 处理字符串的方式不同。

在python2运行"665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569".decode("hex")returns这串字符"f\ ��Q~S�?ۛM -0�V��GE�i"传递给hmac.new()

我在 Python3 搜索后尝试过的东西:

bytes.fromhex('665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569').decode('utf-8')

bytes.fromhex('665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569').decode('ascii')

import binascii
binascii.unhexlify(b"665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569")

但是这些都错误或输出不同的 returns hmac.new() 不会接受。我假设有一个我只是不知道的简单修复,因为我不太了解 p2 和 p3 如何处理字符串的细微差别。

您的一次尝试是正确的:

In [1]: import binascii
   ...: binascii.unhexlify(b"665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569")
   ...:
Out[1]: b'f\ \xb3\xc4Q~\x02S\x11\x16\x0b\x7f\xec?\xdb\x9bM\t\x1f\x14-0\x8cV\x8d\x0e\xecGE\xf5i'

如果您之后从 hmac 中得到错误的结果,您可以 post 提出有关该特定场景的问题,并提供一些比较 python2/3.

的示例

您可能 运行 遇到消息本身的问题,它需要明确使用字节,而不是字符串。这两个给出相同的值:

Python 3:

In [10]: hmac.new(binascii.unhexlify(b"665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569"),
    ...:   msg="whatever".encode('utf-8'),
    ...:   digestmod=hashlib.sha256).hexdigest()
Out[10]: '79ca98357629c22a094c67a02638076573ec41d2c5ce8996435656f8488552d0'

Python 2:

>>> hmac.new("665c20b3c4517e025311160b7fec3fdb9b4d091f142d308c568d0eec4745f569".decode("hex"),
...                                      msg="whatever",
...                                      digestmod=hashlib.sha256).hexdigest()
'79ca98357629c22a094c67a02638076573ec41d2c5ce8996435656f8488552d0'