python - hmac 新 sha1
python - hmac new sha1
我正在尝试获得与 this online API service produces 相同的结果。
通过输入 key
作为应用程序密钥,并输入 secret
作为秘密生成以下 URL:
http://webservices.esd.org.uk/organisations/barrowbc?ApplicationKey=key&Signature=YXWJsGSKnLcENW1vm30EYObbCsA=
我尝试使用以下代码生成相同的签名:
import hmac
import urllib
import base64
from hashlib import sha1
def sign_url(url,key,secret):
url = url + 'ApplicationKey=' + key
signature = hmac.new(secret,url,sha1).digest().encode("base64")
signature = '&Signature=' + signature
url = url + signature
print(url)
sign_url('http://webservices.esd.org.uk/organisations/barrowbc','key','secret')
但这会产生:
http://webservices.esd.org.uk/organisations/barrowbcApplicationKey=key&Signature=W//jgV+xdSbTBG6+i1TCGN/Kbsk=
预期的签名是
YXWJsGSKnLcENW1vm30EYObbCsA=
但我的代码输出
W//jgV+xdSbTBG6+i1TCGN/Kbsk=
您的版本在 Application=
参数之前缺少必需的 ?
组件。但是,如果还有其他参数,您可能想添加一个 &
,并且您需要删除 .encode("base64")
添加到值末尾的换行符:
def sign_url(url, key, secret):
sep = '&' if '?' in url else '?'
url = '{}{}ApplicationKey={}'.format(url, sep, key)
signature = hmac.new(secret, url, sha1).digest().encode("base64")
return '{}&Signature={}'.format(url, signature[:-1])
但是我注意到,当 URL 包含 URL- 编码元素时 然后签名似乎应用于 URL-解码版本(+
被解释为空格),所以你真的想添加一个 urllib.unquote_plus()
(Python 2) / urllib.parse.unquote_plus()
(Python 3) 调用签名:
try:
from urllib.parse import unquote_plus
except ImportError:
from urlib import unquote_plus
def sign_url(url, key, secret):
sep = '&' if '?' in url else '?'
url = '{}{}ApplicationKey={}'.format(url, sep, key)
signature = hmac.new(secret, unquote_plus(url), sha1).digest().encode("base64")
return '{}&Signature={}'.format(url, signature[:-1])
我已经确认这就是他们的 PHP example code does and verified sample query parameters in the online signature tool, e.g. when entering the path and parameters foo%20bar?foo%20bar
into the tool, CCuMYpCDznH4vIv95+NrN+RHEK0=
is produced as the signature, but using foo+bar?foo+bar
produces the exact same signature even though +
should only be decoded as a space in form data。
我先解析出URL,在解析出的参数中加入ApplicationKey
参数,然后构造一个新的URL进行签名。
这是一个版本,可以在 Python 2 和 Python 3 上运行:
import hmac
import base64
from hashlib import sha1
try:
# Python 3
from urllib.parse import parse_qsl, unquote_plus, urlencode, urlparse
except ImportError:
# Python 2
from urlparse import urlparse, parse_qsl
from urllib import unquote_plus, urlencode
def sign_url(url, key, secret):
parsed = urlparse(url)
query = parse_qsl(parsed.query)
query.append(('ApplicationKey', key))
to_sign = unquote_plus(parsed._replace(query=urlencode(query)).geturl())
if not isinstance(secret, bytes):
secret = secret.encode()
if not isinstance(to_sign, bytes):
to_sign = to_sign.encode()
signature = base64.b64encode(hmac.new(secret, to_sign, sha1).digest())
if not isinstance(signature, str):
signature = signature.decode()
query.append(('Signature', signature))
return parsed._replace(query=urlencode(query)).geturl()
我正在尝试获得与 this online API service produces 相同的结果。
通过输入 key
作为应用程序密钥,并输入 secret
作为秘密生成以下 URL:
http://webservices.esd.org.uk/organisations/barrowbc?ApplicationKey=key&Signature=YXWJsGSKnLcENW1vm30EYObbCsA=
我尝试使用以下代码生成相同的签名:
import hmac
import urllib
import base64
from hashlib import sha1
def sign_url(url,key,secret):
url = url + 'ApplicationKey=' + key
signature = hmac.new(secret,url,sha1).digest().encode("base64")
signature = '&Signature=' + signature
url = url + signature
print(url)
sign_url('http://webservices.esd.org.uk/organisations/barrowbc','key','secret')
但这会产生:
http://webservices.esd.org.uk/organisations/barrowbcApplicationKey=key&Signature=W//jgV+xdSbTBG6+i1TCGN/Kbsk=
预期的签名是
YXWJsGSKnLcENW1vm30EYObbCsA=
但我的代码输出
W//jgV+xdSbTBG6+i1TCGN/Kbsk=
您的版本在 Application=
参数之前缺少必需的 ?
组件。但是,如果还有其他参数,您可能想添加一个 &
,并且您需要删除 .encode("base64")
添加到值末尾的换行符:
def sign_url(url, key, secret):
sep = '&' if '?' in url else '?'
url = '{}{}ApplicationKey={}'.format(url, sep, key)
signature = hmac.new(secret, url, sha1).digest().encode("base64")
return '{}&Signature={}'.format(url, signature[:-1])
但是我注意到,当 URL 包含 URL- 编码元素时 然后签名似乎应用于 URL-解码版本(+
被解释为空格),所以你真的想添加一个 urllib.unquote_plus()
(Python 2) / urllib.parse.unquote_plus()
(Python 3) 调用签名:
try:
from urllib.parse import unquote_plus
except ImportError:
from urlib import unquote_plus
def sign_url(url, key, secret):
sep = '&' if '?' in url else '?'
url = '{}{}ApplicationKey={}'.format(url, sep, key)
signature = hmac.new(secret, unquote_plus(url), sha1).digest().encode("base64")
return '{}&Signature={}'.format(url, signature[:-1])
我已经确认这就是他们的 PHP example code does and verified sample query parameters in the online signature tool, e.g. when entering the path and parameters foo%20bar?foo%20bar
into the tool, CCuMYpCDznH4vIv95+NrN+RHEK0=
is produced as the signature, but using foo+bar?foo+bar
produces the exact same signature even though +
should only be decoded as a space in form data。
我先解析出URL,在解析出的参数中加入ApplicationKey
参数,然后构造一个新的URL进行签名。
这是一个版本,可以在 Python 2 和 Python 3 上运行:
import hmac
import base64
from hashlib import sha1
try:
# Python 3
from urllib.parse import parse_qsl, unquote_plus, urlencode, urlparse
except ImportError:
# Python 2
from urlparse import urlparse, parse_qsl
from urllib import unquote_plus, urlencode
def sign_url(url, key, secret):
parsed = urlparse(url)
query = parse_qsl(parsed.query)
query.append(('ApplicationKey', key))
to_sign = unquote_plus(parsed._replace(query=urlencode(query)).geturl())
if not isinstance(secret, bytes):
secret = secret.encode()
if not isinstance(to_sign, bytes):
to_sign = to_sign.encode()
signature = base64.b64encode(hmac.new(secret, to_sign, sha1).digest())
if not isinstance(signature, str):
signature = signature.decode()
query.append(('Signature', signature))
return parsed._replace(query=urlencode(query)).geturl()