Python3 和 hmac 。如何处理不是二进制的字符串
Python3 and hmac . How to handle string not being binary
我在 Python2 中有一个运行良好的脚本。
def _generate_signature(data):
return hmac.new('key', data, hashlib.sha256).hexdigest()
其中数据是 json.dumps
的输出。
现在,如果我尝试 运行 Python 3 中的相同类型的代码,我会得到以下结果:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.4/hmac.py", line 42, in __init__
raise TypeError("key: expected bytes or bytearray, but got %r" %type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'
如果我尝试像这样将密钥转换为字节:
bytes('key')
我明白了
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
我仍在努力理解 Python 3.
中的编码
您可以使用字节文字:b'key'
def _generate_signature(data):
return hmac.new(b'key', data, hashlib.sha256).hexdigest()
除此之外,确保 data
也是字节。比如从文件中读取,打开文件时需要使用binary
方式(rb
)。
不是要复活一个老问题,而是我确实想补充一些我觉得这个答案中缺少的东西,我很难找到其他任何地方的合适 explanation/example:
Aquiles Carattino 非常接近他将字符串转换为字节的尝试,但缺少第二个参数,即要转换为字节的字符串的编码。
如果有人想通过静态分配以外的其他方式(例如从配置文件或数据库中读取)将字符串转换为字节,则以下方法应该可行:
(Python 仅 3+,不兼容 Python 2)
import hmac, hashlib
def _generate_signature(data):
key = 'key' # Defined as a simple string.
key_bytes= bytes(key , 'latin-1') # Commonly 'latin-1' or 'ascii'
data_bytes = bytes(data, 'latin-1') # Assumes `data` is also an ascii string.
return hmac.new(key_bytes, data_bytes , hashlib.sha256).hexdigest()
print(
_generate_signature('this is my string of data')
)
尝试
codecs.encode()
可用于python2.7.12 和 3.5.2
import hashlib
import codecs
import hmac
a = "aaaaaaa"
b = "bbbbbbb"
hmac.new(codecs.encode(a), msg=codecs.encode(b), digestmod=hashlib.sha256).hexdigest()
对于 python3 我就是这样解决的。
import codecs
import hmac
def _generate_signature(data):
return hmac.new(codecs.encode(key), codecs.encode(data), codecs.encode(hashlib.sha256)).hexdigest()
我在 Python2 中有一个运行良好的脚本。
def _generate_signature(data):
return hmac.new('key', data, hashlib.sha256).hexdigest()
其中数据是 json.dumps
的输出。
现在,如果我尝试 运行 Python 3 中的相同类型的代码,我会得到以下结果:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/hmac.py", line 144, in new
return HMAC(key, msg, digestmod)
File "/usr/lib/python3.4/hmac.py", line 42, in __init__
raise TypeError("key: expected bytes or bytearray, but got %r" %type(key).__name__)
TypeError: key: expected bytes or bytearray, but got 'str'
如果我尝试像这样将密钥转换为字节:
bytes('key')
我明白了
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding
我仍在努力理解 Python 3.
中的编码您可以使用字节文字:b'key'
def _generate_signature(data):
return hmac.new(b'key', data, hashlib.sha256).hexdigest()
除此之外,确保 data
也是字节。比如从文件中读取,打开文件时需要使用binary
方式(rb
)。
不是要复活一个老问题,而是我确实想补充一些我觉得这个答案中缺少的东西,我很难找到其他任何地方的合适 explanation/example:
Aquiles Carattino 非常接近他将字符串转换为字节的尝试,但缺少第二个参数,即要转换为字节的字符串的编码。
如果有人想通过静态分配以外的其他方式(例如从配置文件或数据库中读取)将字符串转换为字节,则以下方法应该可行:
(Python 仅 3+,不兼容 Python 2)
import hmac, hashlib
def _generate_signature(data):
key = 'key' # Defined as a simple string.
key_bytes= bytes(key , 'latin-1') # Commonly 'latin-1' or 'ascii'
data_bytes = bytes(data, 'latin-1') # Assumes `data` is also an ascii string.
return hmac.new(key_bytes, data_bytes , hashlib.sha256).hexdigest()
print(
_generate_signature('this is my string of data')
)
尝试
codecs.encode()
可用于python2.7.12 和 3.5.2
import hashlib
import codecs
import hmac
a = "aaaaaaa"
b = "bbbbbbb"
hmac.new(codecs.encode(a), msg=codecs.encode(b), digestmod=hashlib.sha256).hexdigest()
对于 python3 我就是这样解决的。
import codecs
import hmac
def _generate_signature(data):
return hmac.new(codecs.encode(key), codecs.encode(data), codecs.encode(hashlib.sha256)).hexdigest()