首页 > 解决方案 > 验证来自 Transnational webhook 的 webhook 帖子签名

问题描述

我试图验证来自跨国支付的 webhook 帖子签名。有这方面的文件;

Webhook post requests are sent with a header "Signature" that is HMAC SHA 256 signed and then base64 url encoded.

To verify webhook post signatures, retrieve "Signature" from header. Base64 url decode and use HMAC SHA 256 to check using your signature UUID located in the control panel under the webhook previously created

首先,当我尝试使用 Base64 Url 解码签名时,我得到一个错误。这是一个签名的例子。“RwtK6Kr4NOOFs9mjYPpEJWxSJQr23k6uXDktj4QEjGk”

这是他们用来测试签名比较的示例代码:,我认为它在 Go 中。

sig := r.Header.Get("Signature")
// Get the body
body, _ := ioutil.ReadAll(r.Body)
r.Body.Close()
// Verify Sig
mac := hmac.New(sha256.New, []byte("signature-to-check-here"))
mac.Write(body)
sigCheck, _ := base64.RawURLEncoding.DecodeString(sig)
doesitequal := hmac.Equal(sigCheck, mac.Sum(nil))
ctx.Log().Infof("%v", doesitequal)

他们还发送了用于对签名进行编码的代码。

// Set webhook data into buffer for http post
    buf := &bytes.Buffer{}
    enc := json.NewEncoder(buf)
    enc.SetEscapeHTML(true)
    enc.Encode(w.Data)
    // Encrypt the data for signature
    mac := hmac.New(sha256.New, []byte(w.Signature))
    mac.Write(buf.Bytes())
    base64Enc := base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
    // Create post request
    client := &http.Client{
           Timeout: time.Duration(5 * time.Second),
    }
    req, err := http.NewRequest("POST", w.URL, bytes.NewReader(buf.Bytes()))
    if err != nil {
           ctx.Log().AddField("Webhook data", w).Error(err.Error())
    }
    req.Header.Set("Content-type", "application/json")
    req.Header.Set("Signature", base64Enc)

这是我尝试过的 1 个版本。我正在尝试从响应中创建签名并将其与标头中的签名相匹配。我找不到比赛。这不会尝试

 Encoding ascii = Encoding.ASCII;


        var client_secret = "[Secret]";

        //request body
        var body = "[Responce Body]";

        // signature form header
        var signature = "RwtK6Kr4NOOFs9mjYPpEJWxSJQr23k6uXDktj4QEjGk";

        // uri escape the body
        var calc_body = Uri.EscapeUriString(body);

        //url encode te body
        calc_body = WebUtility.UrlEncode(calc_body);

        //create the signature HMACSHA256    
        var sig = GenerateSignature(calc_body, client_secret);

        //Base64 Url encode the signture
        var calc_sig = Base64UrlEncode(ascii.GetBytes(sig));

        //Compare the signature form the header to the calculated cignature
        if (signature == calc_sig)
        {

            Console.WriteLine("Matches");

        }
        else
        {

            Console.WriteLine("Does not match");

        }
    }

    private static string GenerateSignature(string data, string signatureKey)
    {
        var keyByte = Encoding.ASCII.GetBytes(signatureKey);
        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            hmacsha256.ComputeHash(Encoding.ASCII.GetBytes(data));
            return hmacsha256.Hash.Aggregate("", (current, t) => current + t.ToString("X2")).ToLower();
        }
    }

    static string Base64UrlEncode(byte[] arg)
    {
        var s = Convert.ToBase64String(arg); // Regular base64 encoder
        s = s.Split('=')[0]; // Remove any trailing '='s
        s = s.Replace('+', '-'); // 62nd char of encoding
        s = s.Replace('/', '_'); // 63rd char of encoding
        return s;
    }

我什至不确定我的步骤是否正确。

提前感谢您的帮助。

标签: c#webhooks.net-5

解决方案


推荐阅读