[英]Shopify HMAC parameter verification failing in Python
我在驗證來自 Shopify 的 HMAC 參數時遇到了一些問題。 我根據Shopify 文檔使用的代碼返回了錯誤的結果。
這是我的注釋代碼:
import urllib
import hmac
import hashlib
qs = "hmac=96d0a58213b6aa5ca5ef6295023a90694cf21655cf301975978a9aa30e2d3e48&locale=en&protocol=https%3A%2F%2F&shop=myshopname.myshopify.com×tamp=1520883022"
解析查詢字符串
params = urllib.parse.parse_qs(qs)
提取 hmac 值
value = params['hmac'][0]
從每個文檔的查詢字符串中刪除參數
del params['hmac']
del params['signature']
重新組合參數
new_qs = urllib.parse.urlencode(params)
計算摘要
h = hmac.new(SECRET.encode("utf8"), msg=new_qs.encode("utf8"), digestmod=hashlib.sha256)
返回False
!
hmac.compare_digest(h.hexdigest(), value)
從表面上看,最后一步應該返回 true。 此處遵循的每一步都按照 Shopify 文檔中的評論進行了概述。
我將發布我自己問題的答案,因為在梳理了 Shopify 的論壇和 SO 的其余部分之后,我找不到任何可以明確回答這個問題的內容。
最近,Shopify 開始在查詢字符串負載中包含protocol
參數。 這本身不會成為問題,除了Shopify 在其文檔中忽略提及:
和/
在檢查簽名時不進行 URL 編碼的事實。 這完全是荒謬的,因為他們自己在他們提供的查詢字符串中對這些字符進行URL 編碼。
因此,要解決此問題,只需為urllib.parse.urlencode
提供safe
參數,其值為:/
(擬合,對嗎?)。 完整的工作代碼如下所示:
params = urllib.parse.parse_qsl(qs)
cleaned_params = []
hmac_value = dict(params)['hmac']
# Sort parameters
for (k, v) in sorted(params):
if k in ['hmac', 'signature']:
continue
cleaned_params.append((k, v))
new_qs = urllib.parse.urlencode(cleaned_params, safe=":/")
secret = SECRET.encode("utf8")
h = hmac.new(secret, msg=new_qs.encode("utf8"), digestmod=hashlib.sha256)
# Compare digests
hmac.compare_digest(h.hexdigest(), hmac_value)
希望這對遇到此問題的其他人有所幫助!
請注意,此代碼有些簡化,因為查詢參數不是按字典(按字母順序)排序的。
如果可以更清楚地說明這一點,我也可以更新代碼來做到這一點。
import hmac
import hashlib
...
# Inside your view in Django's views.py
params = request.GET.dict()
#
myhmac = params.pop('hmac')
params['state'] = int(params['state'])
line = '&'.join([
'%s=%s' % (key, value)
for key, value in sorted(params.items())
])
print(line)
h = hmac.new(
key=SHARED_SECRET.encode('utf-8'),
msg=line.encode('utf-8'),
digestmod=hashlib.sha256
)
# Cinderella ?
print(hmac.compare_digest(h.hexdigest(), myhmac))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.