首页 > 解决方案 > Webhook 中的哈希验证

问题描述

我正在努力建立与名为Printify的服务的集成。我正在设置 webhook,最后一步我面临困难:哈希码的安全性。API 文档:https ://developers.printify.com/#webhooks --->保护您的 Webhooks

流程如下:

  1. 通过 http api 创建一个 webhook 并传递一个额外的标头x-pfy-signature,其中包含一个密钥和一个我的系统将监听的可调用 url。
  2. 当调用 webhook 事件时,将调用该可调用 url。
  3. 我应该使用该密钥验证请求正文,以确保它是来自Printify的合法调用。

第 3 步是我遇到问题的地方。他们给出了 Python 中的示例代码:

import os
import hmac

def sha256hash(request):
    hash = hmac.new(os.environ['SECRET_TOKEN'].encode('utf-8'),
                    request.data.encode('utf-8'), 
                    'sha256')
    return 'sha256=' + hash.hexdigest()


def secure_compare(a, b):
    return hmac.compare_digest(a, b)


print('%r' % secure_compare(request.headers['x-pfy-signature'],
                            sha256hash(request)))

看来我正在通过输入从Printify收到的请求正文以及密钥来创建一些编码字符串,然后验证编码字符串是否与请求标头x-pfy-signature 匹配,这与初始的相同我通过了?

有人可以验证这是正确的并概述如何使用 Node 执行此操作吗?

标签: javapythonsecurityhash

解决方案


这是一个 NodeJS 解决方案:https ://bytethisstore.com/articles/pg/printify-webhooks-node-js

该文档实际上缺少一个步骤。创建密钥时,必须在创建 webhook 时将其作为名为“secret”的第三个参数发送。这是文档中缺少的部分。

因此,当您创建 webhook 时,您会发送:

{
    "topic": "order:created",
    "url": "{webhook_callback_url}",
    "secret": "{secret_key}"
}

然后,每当 Printify 向您的端点发送数据时,它们都会使用该密钥对响应进行哈希处理,并将该哈希值作为 x-pfy-signature 标头发送。

就像在他们的 python 示例中一样,您必须比较哈希,而不是密钥本身。您需要使用密钥对发送到 webhook 的数据进行哈希处理,然后将您的哈希值与发送的签名进行比较。就像你描述的那样。

在 PHP 中这要容易得多,这是我用来检查签名的函数:

function validate_webhook($request, $signature): bool
{
    $signature = str_replace('sha256=', '', $signature);
    $hash = hash_hmac('sha256', $request, {secret_key});
    return hash_equals($signature, $hash);
}

其中$request是请求的主体,$signature是 x-pfy-signature 标头的内容。


推荐阅读