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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31848293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 10:39:25  来源:igfitidea点击:

Python3 and hmac . How to handle string not being binary

pythonstringpython-3.xencodinghmac

提问by Aquiles Carattino

I had a script in Python2 that was working great.

我在 Python2 中有一个运行良好的脚本。

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

Where data was the output of json.dumps.

其中 data 是json.dumps.

Now, if I try to run the same kind of code in Python 3, I get the following:

现在,如果我尝试在 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'

If I try something like transforming the key to bytes like so:

如果我尝试将密钥转换为字节,如下所示:

bytes('key')

I get

我得到

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding

I'm still struggling to understand the encodings in Python 3.

我仍在努力理解 Python 3 中的编码。

采纳答案by falsetru

You can use bytes literal: b'key'

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

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

In addition to that, make sure datais also bytes. For example, if it is read from file, you need to use binarymode (rb) when opening the file.

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

回答by Joshua Burns

Not to resurrect an old question but I did want to add something I feel is missing from this answer, to which I had trouble finding an appropriate explanation/example of anywhere else:

不是复活一个老问题,但我确实想添加一些我觉得从这个答案中遗漏的东西,我无法找到其他任何地方的适当解释/示例:

OP Aquiles Carattino was pretty close with his attempt at converting the string to bytes, but was missing the second argument, the encoding of the string to be converted to bytes.

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

If someone would like to convert a string to bytes through some other means than static assignment (such as reading from a config file or a DB), the following should work:

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

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

回答by tinyhare

try

尝试

codecs.encode()

编解码器.encode()

which can be used both in python2.7.12 and 3.5.2

在 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 hereenter image description here

在此处输入图片说明在此处输入图片说明