Python3和hmac。如何处理字符串不是二进制

时间:2015-08-06 06:28:49

标签: python string python-3.x encoding hmac

我在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中的编码。

3 个答案:

答案 0 :(得分:30)

您可以使用字节文字:b'key'

def _generate_signature(data):
    return hmac.new(b'key', data, hashlib.sha256).hexdigest()

除此之外,请确保data也是字节。例如,如果从文件中读取,则在打开文件时需要使用binary模式(rb)。

答案 1 :(得分:20)

不要复活一个旧问题,但我确实想要添加一些我认为在这个答案中缺少的东西,我无法在其他任何地方找到合适的解释/示例:

OP Aquiles Carattino与将字符串转换为字节的尝试非常接近,但是缺少第二个参数,即要转换为字节的字符串的编码。

如果有人想通过静态分配之外的其他方式将字符串转换为字节(例如从配置文件或数据库中读取),则以下内容应该有效:

import hmac, hashlib

def _generate_signature(data):
  key = 'key' # Defined as a simple string.
  key_bytes= bytes(key , 'latin-1')
  data_bytes = bytes(data, 'latin-1') # Assumes `data` is also a string.
  return hmac.new(key_bytes, data_bytes , hashlib.sha256).hexdigest()

print(
  _generate_signature('this is my string of data')
)

答案 2 :(得分:1)

尝试

  

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()

enter image description here enter image description here