I am having a slight problem with HMAC. When running this piece of code:
我对HMAC有轻微的问题。运行这段代码时:
signature = hmac.new(
key=secret_key,
msg=string_to_sign,
digestmod=sha1,
)
I get a strange error:
我收到一个奇怪的错误:
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/hmac.py", line 133, in new
return HMAC(key, msg, digestmod)
File "/usr/local/Cellar/python/2.7.6/Frameworks/Python.framework/Versions/2.7/lib/python2.7/hmac.py", line 72, in __init__
self.outer.update(key.translate(trans_5C))
TypeError: character mapping must return integer, None or unicode
When I print string_to_sign, it is a proper string like this:
当我打印string_to_sign时,它是一个正确的字符串,如下所示:
GET
\n
\n
application/json
\n
\n
\n
What does the error mean? Is it because of new lines?
错误是什么意思?是因为新线?
4 个解决方案
#1
32
As asked I'll post this as an answer. The error that you faced is a feature of Python's HMAC. It does not accept unicode. This feature is described here.
如我所知,我会将此作为答案发布。您遇到的错误是Python HMAC的一个特性。它不接受unicode。此功能在此处描述。
HMAC is a function which works at byte level. For this reason in Python 3 it accepts only bytes
. In Python 2 we don't have bytes
so it accepts only str
.
HMAC是一个在字节级工作的函数。出于这个原因,在Python 3中它只接受字节。在Python 2中,我们没有字节,所以它只接受str。
#2
12
Ensure that "key" and "msg" is a string.such as:
确保“key”和“msg”是一个字符串。如:
s = hmac.new(str(secretkey), str(message), digestmod=hashlib.sha1).hexdigest()
s = hmac.new(str(secretkey),str(message),digestmod = hashlib.sha1).hexdigest()
#3
1
Since I didn't want to write in our API docs that you should convert the payload to ASCII or drop Unicode characters before comparing digests, I've used the following solution:
由于我不想在我们的API文档中写入您应该在比较摘要之前将有效负载转换为ASCII或删除Unicode字符,因此我使用了以下解决方案:
import hmac
import hashlib
def sign_request(self, secret, data):
return hmac.new(
key=bytearray(secret, 'utf-8'),
msg=bytearray(data, 'utf-8'),
digestmod=hashlib.sha256
).hexdigest()
-
bytearray
turns my unicode string into bytes using theutf-8
encoding. - bytearray使用utf-8编码将我的unicode字符串转换为字节。
-
key
andmsg
are bytes parameters (likehmac
library is expecting). - key和msg是字节参数(就像hmac库所期望的那样)。
#4
1
In python 2
在python 2中
If you code it as:
如果您将其编码为:
from __future__ import unicode_literals
import base64
import hashlib
import hmac
import time
def gen_signature(key, strsome, expires=0):
expires = int(time.time()) + 600 if expires == 0 else expires
_2_signature = '%s\n%s\n' % (expires, strsome)
# hmac.new(key, msg, digestmod) bytearray(secret, 'utf-8')
signature = base64.b64encode(hmac.new(key, _2_signature, hashlib.sha1).digest())
return signature
gen_signature('xxxxxxx', 'strsome')
you get an error like the one you provided. However, if you use bytearray(key, 'utf-8')
in place of the raw key variable and bytearray(_2_signature, 'utf-8')
in place place of the _2_signature variable, it should work properly.
你得到的错误就像你提供的那样。但是,如果使用bytearray(key,'utf-8')代替原始键变量和bytearray(_2_signature,'utf-8')代替_2_signature变量,它应该可以正常工作。
For example:
例如:
def gen_signature(key, strsome, expires=0):
expires = int(time.time()) + 600 if expires == 0 else expires
_2_signature = '%s\n%s\n' % (expires, strsome)
# hmac.new(key, msg, digestmod) bytearray(secret, 'utf-8')
signature = base64.b64encode(hmac.new(bytearray(key, 'utf-8'), bytearray(_2_signature, 'utf-8'), hashlib.sha1).digest())
return signature
gen_signature('xxxxxxx', 'strsome')
#1
32
As asked I'll post this as an answer. The error that you faced is a feature of Python's HMAC. It does not accept unicode. This feature is described here.
如我所知,我会将此作为答案发布。您遇到的错误是Python HMAC的一个特性。它不接受unicode。此功能在此处描述。
HMAC is a function which works at byte level. For this reason in Python 3 it accepts only bytes
. In Python 2 we don't have bytes
so it accepts only str
.
HMAC是一个在字节级工作的函数。出于这个原因,在Python 3中它只接受字节。在Python 2中,我们没有字节,所以它只接受str。
#2
12
Ensure that "key" and "msg" is a string.such as:
确保“key”和“msg”是一个字符串。如:
s = hmac.new(str(secretkey), str(message), digestmod=hashlib.sha1).hexdigest()
s = hmac.new(str(secretkey),str(message),digestmod = hashlib.sha1).hexdigest()
#3
1
Since I didn't want to write in our API docs that you should convert the payload to ASCII or drop Unicode characters before comparing digests, I've used the following solution:
由于我不想在我们的API文档中写入您应该在比较摘要之前将有效负载转换为ASCII或删除Unicode字符,因此我使用了以下解决方案:
import hmac
import hashlib
def sign_request(self, secret, data):
return hmac.new(
key=bytearray(secret, 'utf-8'),
msg=bytearray(data, 'utf-8'),
digestmod=hashlib.sha256
).hexdigest()
-
bytearray
turns my unicode string into bytes using theutf-8
encoding. - bytearray使用utf-8编码将我的unicode字符串转换为字节。
-
key
andmsg
are bytes parameters (likehmac
library is expecting). - key和msg是字节参数(就像hmac库所期望的那样)。
#4
1
In python 2
在python 2中
If you code it as:
如果您将其编码为:
from __future__ import unicode_literals
import base64
import hashlib
import hmac
import time
def gen_signature(key, strsome, expires=0):
expires = int(time.time()) + 600 if expires == 0 else expires
_2_signature = '%s\n%s\n' % (expires, strsome)
# hmac.new(key, msg, digestmod) bytearray(secret, 'utf-8')
signature = base64.b64encode(hmac.new(key, _2_signature, hashlib.sha1).digest())
return signature
gen_signature('xxxxxxx', 'strsome')
you get an error like the one you provided. However, if you use bytearray(key, 'utf-8')
in place of the raw key variable and bytearray(_2_signature, 'utf-8')
in place place of the _2_signature variable, it should work properly.
你得到的错误就像你提供的那样。但是,如果使用bytearray(key,'utf-8')代替原始键变量和bytearray(_2_signature,'utf-8')代替_2_signature变量,它应该可以正常工作。
For example:
例如:
def gen_signature(key, strsome, expires=0):
expires = int(time.time()) + 600 if expires == 0 else expires
_2_signature = '%s\n%s\n' % (expires, strsome)
# hmac.new(key, msg, digestmod) bytearray(secret, 'utf-8')
signature = base64.b64encode(hmac.new(bytearray(key, 'utf-8'), bytearray(_2_signature, 'utf-8'), hashlib.sha1).digest())
return signature
gen_signature('xxxxxxx', 'strsome')