[英]Encoding PHP POST response's JSON body into HMAC SHA256, and then into Base64
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.