如何使用HMACSHA256 python 3验证Xero Webhook有效负载

时间:2019-09-13 06:41:17

标签: webhooks python-3.7 sha256 hmac xero-api

根据此处(https://developer.xero.com/documentation/webhooks/configuring-your-server)的说明设置和验证Xero Webhook的接收意图。

计算出的签名应与标头中的签名匹配,以获取正确签名的有效载荷。

但是,使用python 3,计算出的签名根本不匹配标头中的签名。 Xero会向订阅的Webhook URL发送大量请求,以获取正确和不正确的请求。在我的日志中,所有这些请求均返回401。因此,下面是我的测试代码,事实证明该代码也不匹配。我不知道缺少了什么,或者我做错了什么。 不用担心这里显示的密钥,我已经生成了另一个密钥,但这是此时分配给我用于哈希的密钥。 根据他们的指令,运行此代码应使签名与标头之一匹配。但根本没有关闭。

XERO_KEY = 
"lyXWmXrha5MqWWzMzuX8q7aREr/sCWyhN8qVgrW09OzaqJvzd1PYsDAmm7Au+oeR5AhlpHYalba81hrSTBeKAw=="

def create_sha256_signature(key, message):
    message = bytes(message, 'utf-8')
    return base64.b64encode(hmac.new(key.encode(), message, 
                 digestmod=hashlib.sha256).digest()).decode()

# first request header (possibly the incorrect one)
header = "onoTrUNvGHG6dnaBv+JBJxFod/Vp0m0Dd/B6atdoKpM="

# second request header (possibly the correct one)
header = "onoTrUNvGHG6dnaBv+JBJxFodKVp0m0Dd/B6atdoKpM="
payload = {
    'events':[],
    'firstEventSequence':0,
    'lastEventSequence':0,
    'entropy':
    'YSXCMKAQBJOEMGUZEPFZ'
}
payload = json.dumps(payload, separators=(",", ":")).strip()
signature = create_sha256_signature(XERO_KEY, str(payload))
if hmac.compare_digest(header, signature):
     print(True)
     return 200
else:
     print(False)
     return 401

2 个答案:

答案 0 :(得分:0)

问题是因为当我收到请求有效负载时,我正在使用

# flask request
request.get_json()

这将自动将我的请求数据解析为json格式,因此计算出的签名从未匹配的原因

所以,我所做的就是更改了接收请求有效负载的方式:

request.get_data()

这将获取原始数据。

答案 1 :(得分:0)

即使使用 OP 的答案,我仍然无法使其正常工作,我发现这有点含糊。

我发现有效的方法是:

    key = #{your key}
    provided_signature = request.headers.get('X-Xero-Signature')
    hashed = hmac.new(bytes(key, 'utf8'), request.data, hashlib.sha256)
    generated_signature = base64.b64encode(hashed.digest()).decode('utf-8')
    if provided_signature != generated_signature:
        return '', 401
    else:
        return '', 200

发现于 https://github.com/davidvartanian/xero_api_test/blob/master/webhook_server.py#L34