将Python3中的hmac.new()的字符串转换为字节对象
来自的代码示例显示了一个脚本,该脚本可用于从python 2.7中的服务下载日志 我正在更新脚本,使其与python 3兼容,但无法确定如何将字符串传递到hmac.new部分以生成哈希:将Python3中的hmac.new()的字符串转换为字节对象,python,Python,来自的代码示例显示了一个脚本,该脚本可用于从python 2.7中的服务下载日志 我正在更新脚本,使其与python 3兼容,但无法确定如何将字符串传递到hmac.new部分以生成哈希: SECRET_KEY = 'SECRET KEY FOR YOUR ADMINISTRATOR' secret_key = SECRET_KEY def create_signature(data_to_sign, secret_key): digest = hmac.new(secret_ke
SECRET_KEY = 'SECRET KEY FOR YOUR ADMINISTRATOR'
secret_key = SECRET_KEY
def create_signature(data_to_sign, secret_key):
digest = hmac.new(secret_key.decode("base64"), data_to_sign, digestmod=hashlib.sha1).digest()
return base64.encodestring(digest).rstrip()
尝试按原样运行会导致“LookupError,'base64'不是文本编码;请使用codecs.decode()处理任意编解码器”
我试图使用
base64.b64解码
或字节(密钥)
函数,但这会导致“TypeError,在散列之前必须对Unicode对象进行编码”,我只是没有找到很多关于如何将字符串变量传递到hmac.new()的信息
我很确定这与python 2和3之间的变化有关,其中字符串在3中存储为unicode,在2中是原始数据,但我对这些编码不够熟悉,无法理解在传递它们时如何正确翻译它们。错误消息告诉您需要做什么:
TypeError, Unicode-objects must be encoded before hashing
要编码Unicode对象(即str
),只需调用其方法
你必须决定你想要什么编码。通常,这是UTF-8。如果您使用的是现代Python 3,UTF-8保证是默认值,因此您可以编写以下代码:
secret_key_bytes = secret_key.encode()
如果您想要不同的编码(或者如果您想要UTF-8,但您使用的是较旧的Python),请显式指定它:
secret_key_bytes = secret_key.encode('Latin-1')
错误消息告诉您需要执行的操作:
TypeError, Unicode-objects must be encoded before hashing
要编码Unicode对象(即str
),只需调用其方法
你必须决定你想要什么编码。通常,这是UTF-8。如果您使用的是现代Python 3,UTF-8保证是默认值,因此您可以编写以下代码:
secret_key_bytes = secret_key.encode()
如果您想要不同的编码(或者如果您想要UTF-8,但您使用的是较旧的Python),请显式指定它:
secret_key_bytes = secret_key.encode('Latin-1')
想想什么是
bytes
,什么是str
:
编辑:根据和,要签名的数据
也必须是字节
密钥
是一个str
->将其转换为字节
data\u to\u sign
也可能是一个str
->将其转换为字节
base64.b64解码
接受并输出字节
->不执行任何操作hmac.new
也接受bytes
我们已经准备好了摘要
返回字节
->我们想要b64编码
它,并且b64编码
接受字节
,所以我们很好str
(虽然bytes
可能很好)->decode
解码b64encode
编码参数
代码:
想想什么是bytes
,什么是str
:
编辑:根据和,要签名的数据
也必须是字节
密钥
是一个str
->将其转换为字节
data\u to\u sign
也可能是一个str
->将其转换为字节
base64.b64解码
接受并输出字节
->不执行任何操作
hmac.new
也接受bytes
我们已经准备好了
摘要
返回字节
->我们想要b64编码
它,并且b64编码
接受字节
,所以我们很好
您希望输出一个str
(虽然bytes
可能很好)->decode
解码b64encode
如果要使用不同于默认()的编码,还可以为函数提供编码参数
代码:
作为旁注,IIRC,3.7将为您提供一个不推荐使用的警告,因为新的hmac.digest
没有digestmod
的默认值,它将被完全删除。如果你没有看到这个警告,就把它记下来,这样在3.8中就不会让你感到惊讶了;如果您是,并且不需要与3.4-3.6兼容,只需将new
更改为digest
即可解决此问题。作为旁注,IIRC,3.7将为您提供一个弃用警告,因为新的hmac.digest
没有默认值的digestmod
将完全删除它。如果你没有看到这个警告,就把它记下来,这样在3.8中就不会让你感到惊讶了;如果是,并且不需要与3.4-3.6兼容,只需将新的更改为摘要
就可以解决它。我也尝试过使用.encode().encode('utf-8')和.encode('Latin-1')变体,所有这些都会继续导致“类型错误,Unicode对象必须在散列之前进行编码” problem@ForrestBerrey你必须向我们展示你试过的代码。很明显,您弄错了什么,但是任何人都不可能在没有看到代码的情况下猜出您弄错了什么。您是对的,因为我对hmac.new()文档的解释不正确,所以我错误地认为data_to_sign字段可以作为字符串传递。感谢您的审阅和评论。我也尝试过使用.encode().encode('utf-8')和.encode('Latin-1')变体,所有这些都继续导致“TypeError,Unicode对象必须在散列之前编码”problem@ForrestBerrey你必须向我们展示你试过的代码。很明显,你搞错了,但是任何人都不可能在没有看到代码的情况下猜出你搞错了什么。你是对的,我错误地认为