散列格子请求主体Webhook

2024-10-16 17:23:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试验证Plaid的API发送的webhook。每个webhook请求都会发送一个“plaid验证”头,它是一个JSON Web令牌

验证所需的步骤包括:

  1. 从请求头中提取JWT

signed_jwt = eyJhbGciOiJFUzI1NiIsImtpZCI6IjZjNTUxNmUxLTkyZGMtNDc5ZS1hOGZmLTVhNTE5OTJlMDAwMSIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1OTA4ODcwMDEsInJlcXVlc3RfYm9keV9zaGEyNTYiOiJiNjNhMDdiNTQ3YjAwZjk5MjU0N2Y2YmJjOGQ5YWNjNjFhOGNjZWUxMzhiYzgyZjQ0YTZiYWEwOTY4M2E1ZDBmIn0.OOKvIihgqCj7Qrb2bmz7T3t7uK-0JyjiEqL2s1kWeJBM4MMmjaHKK8GmU_z91QolBWMzvPgs718EElY-rE3cwQ

  1. 在不验证签名的情况下提取JWT头值,如下所示:
    {
      "alg": "ES256",
      "kid": "6c5516e1-92dc-479e-a8ff-5a51992e0001",
      "typ": "JWT"
    }
  1. 提取kid并发布到/webhook_verification_key/get
    POST /webhook_verification_key/get
    {
        "client_id": "MY_CLIENT_ID"
        "secret": "MY_SECRET_ID"
        "key_id": "6c5516e1-92dc-479e-a8ff-5a51992e0001"
    }

答复是:

{
  "key": {
    "alg": "ES256",
    "created_at": 1560466143,
    "crv": "P-256",
    "expired_at": null,
    "kid": "6c5516e1-92dc-479e-a8ff-5a51992e0001",
    "kty": "EC",
    "use": "sig",
    "x": "35lvC8uz2QrWpQJ3TUH8t9o9DURMp7ydU518RKDl20k",
    "y": "I8BuXB2bvxelzJAd7OKhd-ZwjCst05Fx47Mb_0ugros"
  },
  "request_id": "HvfCtrDLG1ihcp7"
}
  1. key解释为JSON Web密钥,验证JSON Web密钥的签名是否有效,并提取有效负载(使用jose python库)
claims = jwt.decode(signed_jwt, key, algorithms=['ES256'])

claims = {
             "iat": 1590887001, 
             "request_body_sha256": "b63a07b547b00f992547f6bbc8d9acc61a8ccee138bc82f44a6baa09683a5d0f"
         }
  1. 计算请求正文的SHA-256并确保它与claims['request_body_sha256']匹配:

Body位于Body.json文件中

{
    "error": null,
    "item_id": "yxQbxDjnD8hr69pKbQpbcKeVn3GL9QuyA7NV3",
    "new_transactions": 390,
    "webhook_code": "HISTORICAL_UPDATE",
    "webhook_type": "TRANSACTIONS"
}

计算body.json的SHA-256

f = open('body.json')
body = json.load(f)
f.close()

m = hashlib.sha256()
m.update(json.dumps(body).encode())
body_hash = m.hexdigest()
print(body_hash)

body_hash = 'efbb5274864518f7eb3834125d9bcdb95fb03066d3d1bed3ebcc6163d8dc3579'

上例中的body散列不等于从Plaid接收的body散列。这里可能有两个问题:

  1. Plaid未发送正确的正文哈希(不太可能)
  2. 我用来散列主体的散列方法与Plaid的方法不同

这里有我遗漏的东西吗?也许请求主体在我这边的编码不同?我在产品中使用Node.js和Express,但是我制作了一个Python脚本来遵循Plaid概述的方法here,但是我仍然没有得到正确的哈希。老实说,我没有主意了


Tags: keywebidjsonrequestbodywebhookjwt
2条回答

我与我们的支持团队分享了这一点,他们发现了这个问题。这似乎是空白的问题。如果修改body.json,使每一新行上的每个“tab”有2个空格,它将生成正确的哈希

亚历克斯是对的。我最近也遇到了同样的问题,而且看起来格子布确实是基于2的标签间距对他们的身体进行散列的。您可以使用JSON.stringify(body,null,2)让一切都愉快:

const happyBody = JSON.stringify(body, null, 2);
const body_hash = crypto
  .createHash("sha256")
  .update(happyBody)
  .digest("hex");

另见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

好处:你可以使用JSON.stringify(object, replacer, space)来美化JSON。最后一个参数的整数将决定要使用的空格数,但如果需要制表符,可以用类似"/t"的内容替换:JSON.stringify(someObject, null, "\t");

相关问题 更多 >