简体   繁体   English

将PHP POST响应的JSON主体编码为HMAC SHA256,然后编码为Base64

[英]Encoding PHP POST response's JSON body into HMAC SHA256, and then into Base64

How to receive raw JSON response from HTTP POST webhook? 如何从HTTP POST webhook接收原始JSON响应?


I am working with an API and to verify that the POST to the webhook is indeed from the appropriate company API, they suggest this method: 我正在使用API​​,并验证到Webhook的POST是否确实来自适当的公司API,他们建议使用以下方法:

To allow a client to verify a webhook message has in fact come from SIGNIFYD, an X-SIGNIFYD-SEC-HMAC-SHA256 header is included in each webhook POST message. 为了允许客户端验证Webhook消息确实来自SIGNIFYD,每个Webhook POST消息中都包含一个X-SIGNIFYD-SEC-HMAC-SHA256标头。 The contents of this header is the Base64 encoded output of the HMAC SHA256 encoding of the JSON body of the message , using the team's API key as the encryption key. 此标头的内容是消息的JSON主体的HMAC SHA256编码的Base64编码输出 ,使用团队的API密钥作为加密密钥。 To verify the authenticity of the webhook message, you should calculate this value yourself and verify it equals the value contained in the header. 要验证webhook消息的真实性,您应该自己计算该值,并验证它等于标头中包含的值。

For the test environment, the "secret" key is ABCDE instead of the "Team API key." 对于测试环境,“秘密”密钥是ABCDE而不是“ Team API密钥”。

I am receiving it in PHP like so: 我在PHP中这样接收它:

<?php

// Get relevant Signifyd custom headers to be used for verification
$header_sig_topic = $_SERVER['HTTP_X_SIGNIFYD_TOPIC'];
$header_sig_sec_hmac = $_SERVER['HTTP_X_SIGNIFYD_SEC_HMAC_SHA256'];

// Get POST body
$webhookContent = "";
$webhook = fopen('php://input' , 'r');
while (!feof($webhook)) {
    $webhookContent .= fread($webhook, 4096);
}
fclose($webhook);

?>

then I am processing it into the hash like so: 然后我将其处理为哈希,如下所示:

<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>

However, I am going wrong somewhere, because the hash I calculate is 但是,我在某处出错,因为我计算出的哈希值是

OTc1YzExZDY2ZTE1MTVmYmJmNWNhNDRhNWMxZGIzZDk0NmM3OGE4NDU2N2JkYTJmZDJlYWI0ODRhNjlhNTdiYg==

while the header for an identical sample response header always comes with 而相同的样本响应标头的标头总是带有

W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=

I thought I was getting the JSOn body wrong somehow so I've tried every combination of json_encode and json_decode but nothing helps, my hash never matches. 我以为我以某种方式弄错了JSOn主体,所以我尝试了json_encode和json_decode的每种组合,但没有任何帮助,我的哈希值永远不匹配。

I've also tried using $webhookContent = json_decode(file_get_contents('php://input'), true); 我也尝试过使用$webhookContent = json_decode(file_get_contents('php://input'), true); to store the POST body but that just comes up empty ($_POST doesn't work either). 来存储POST正文,但这只是空的($ _POST也不起作用)。

Am I doing something else wrong other than receiving the JSON? 除了接收JSON之外,我还有其他问题吗?


The JSON that comes as the body of the test response which always comes with W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY= as the hash key to be used for verification: 作为测试响应主体的JSON始终与W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=一起用作验证的哈希密钥:

{ "analysisUrl": "https://signifyd.com/v2/cases/1/analysis", "entriesUrl": "https://signifyd.com/v2/cases/1/entries", "notesUrl": "https://signifyd.com/v2/cases/1/notes", "orderUrl": "https://signifyd.com/v2/cases/1/order", "guaranteeEligible":false, "status":"DISMISSED", "uuid":"709b9107-eda0-4cdd-bdac-a82f51a8a3f3", "headline":"John Smith", "reviewDisposition":null, "associatedTeam":{ "teamName":"anyTeam", "teamId":26, "getAutoDismiss":true, "getTeamDismissalDays":2 }, "orderId":"19418", "orderDate":"2013-06-17T06:20:47-0700", "orderAmount":365.99, "createdAt":"2013-11-05T14:23:26-0800", "updatedAt":"2013-11-05T14:23:26-0800", "adjustedScore":262.6666666666667, "investigationId":1, "score":262.6666666666667, "caseId":1, "guaranteeDisposition":"APPROVED"}

If it helps to see where I'm going wrong, an example is provided but it's in Python: 如果有助于查看我要去哪里,可以提供一个示例,但该示例在Python中:

Mac sha256HMAC = javax.crypto.Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(teamAPIKEY.getBytes(), "HmacSHA256");
sha256HMAC.init(secretKey);
String encodedHMAC256 = Base64.encodeBase64String(sha256HMAC.doFinal(jsonBody.getBytes("UTF-8")));

My error was in simply not specifying the $raw_output parameter of the hash_hmac() function as true . 我的错误是根本没有hash_hmac()函数$raw_output参数指定为true

raw_output raw_output
When set to TRUE, outputs raw binary data. 设置为TRUE时,输出原始二进制数据。 FALSE outputs lowercase hexits. FALSE输出小写的十六进制。

So, since I wasn't specifying $raw_output as true , I was getting hexits instead of raw binary output, which looked like this: 975c11d66e1515fbbf5ca44a5c1db3d946c78a84567bda2fd2eab484a69a57bb . 因此,由于未将$raw_output指定为true ,所以我得到的是hexits而不是原始二进制输出,如下所示: 975c11d66e1515fbbf5ca44a5c1db3d946c78a84567bda2fd2eab484a69a57bb

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM