来自WooCommerce的SHA256 webhook签名永远不会验证

Lui*_*ado 4 hash webhooks node.js woocommerce

我从一个woocommerce网站收到webhooks到nodejs/express应用程序.我试图验证webhook的签名以证明真实性,但我计算的哈希永远不会对应于woocommerce在钩子的签名头中报告的签名.

这是我用来验证真实性的代码:

function verifySignature(signature, payload, key){     
    var computedSignature = crypto.createHmac("sha256", key).update(payload).digest('base64');
    debug('computed signature: %s', computedSignature);
    return computedSignature === signature;
  }
Run Code Online (Sandbox Code Playgroud)

使用以下参数调用此函数:

var signature = req.headers['x-wc-webhook-signature'];
verifySignature(signature, JSON.stringify(req.body), config.wooCommence.accounts.api[config.env].webhookSecret)
Run Code Online (Sandbox Code Playgroud)

webhook的签名标题将签名报告为BewIV/zZMbmuJkHaUwaQxjX8yR6jRktPZQN9j2+67Oo=.然而,上述操作的结果是S34YqftH1R8F4uH4Ya2BSM1rn0H9NiqEA2Nr7W1CWZs=

我已经在webhook上手动配置了秘密,正如您在上面的代码中所看到的,这个相同的秘密也在快速应用程序中进行了硬编码.因此,要么我正在使用错误的有效负载来计算签名,要么还有其他可疑的东西阻止我验证这些签名.

非常感谢帮助我解决这个问题的任何指示.

Bri*_*ton 6

由于这是该问题的 Google 最高结果,并且没有完整的答案,因此这里有一个使用 Flask 验证 WooCommerce webhook 签名的 Python 版本。经过一番尝试和错误,希望对那里的人有所帮助:

import json
import base64
import hmac
import hashlib

from flask import Flask, request, Response

app = Flask(__name__)

# The WooCommerce webhook secret
WEBHOOK_SECRET = 'abc123456'

# Function that compares the computed signature to the one in the request
def verify_woocommerce_signature(body, signature, secret):
    digest = hmac.new(bytes(secret, 'utf-8'), body, hashlib.sha256).digest()
    encoded = base64.b64encode(digest).decode()

    return encoded == signature

# WooCommerce Order Creation Event
@app.route('/webhooks/woocommerce/order_created', methods=['POST'])
def webhooks_woocommerce_order_created():
    # Get raw request body
    body = request.get_data()
    
    # Get request signature
    signature = request.headers['X-WC-WEBHOOK-SIGNATURE']
    
    # Verify webhook signature and handle mismatch
    if verify_woocommerce_signature(body, signature, WEBHOOK_SECRET) is False:
        msg = {"success": False}
        return Response(json.dumps(msg), status=400, mimetype='application/json')

    # Signatures match, process the payload
Run Code Online (Sandbox Code Playgroud)

  • 奇迹般有效。谢谢你! (2认同)

Jul*_*nec 5

对于使用节点的人来说,这应该可以解决问题.

var processWebHookSignature = function (secret, body, signature) {
  signatureComputed = crypto.createHmac('SHA256', secret).update(
    new Buffer(JSON.stringify(body), 'utf8')).digest('base64');

  return ( signatureComputed === signature ) ? true : false;
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ein 4

老问题,但也许它可以帮助一些可怜的灵魂。需要根据正文而不是其包含的 JSON 检查签名。即主体的原始字节。

伪:

        byte[] body = request.Body;
        string signature = request.Header["X-WC-Webhook-Signature"];

        byte[] secretUtf8 = GetUtf8Bytes("yoursecrethere");
        byte[] hash = HMAC_SHA256.ComputeHash(body, secretUtf8);
        string hashBase64 = ToBase64String(hash);

        bool isValid = hashBase64 == signature;
Run Code Online (Sandbox Code Playgroud)