将 PHP POST 响应的 JSON body 编码为 HMAC SHA256,然后编码为 Base64
Encoding PHP POST response's JSON body into HMAC SHA256, and then into Base64
如何从 HTTP POST webhook 接收原始 JSON 响应?
我正在与 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. 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. To verify the authenticity of the webhook message, you should calculate this value yourself and verify it equals the value contained in the header.
对于测试环境,"secret"键是ABCDE
而不是"Team API key."
我在 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);
?>
然后我像这样将它处理成散列:
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
但是,我哪里出错了,因为我计算的散列是
OTc1YzExZDY2ZTE1MTVmYmJmNWNhNDRhNWMxZGIzZDk0NmM3OGE4NDU2N2JkYTJmZDJlYWI0ODRhNjlhNTdiYg==
而 header 对于相同的样本响应 header 总是带有
W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=
我以为我弄错了 JSOn body 所以我尝试了 json_encode 和 json_decode 的所有组合但没有任何帮助,我的哈希值永远不匹配.
我也尝试过使用 $webhookContent = json_decode(file_get_contents('php://input'), true);
来存储 POST body 但结果是空的($_POST 也不起作用)。
除了收到JSON之外,我是不是做错了什么?
作为测试响应的body出现的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"}
如果有助于了解我哪里出错了,提供了一个示例,但它在 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")));
我的错误是没有将 $raw_output
parameter of the hash_hmac()
function 指定为 true
。
raw_output
When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.
因此,由于我没有将 $raw_output
指定为 true
,我得到的是 hexits
而不是原始二进制输出,它看起来像这样:975c11d66e1515fbbf5ca44a5c1db3d946c78a84567bda2fd2eab484a69a57bb
。
编辑:这里的答案是
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret, true);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
如何从 HTTP POST webhook 接收原始 JSON 响应?
我正在与 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. 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. To verify the authenticity of the webhook message, you should calculate this value yourself and verify it equals the value contained in the header.
对于测试环境,"secret"键是ABCDE
而不是"Team API key."
我在 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);
?>
然后我像这样将它处理成散列:
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>
但是,我哪里出错了,因为我计算的散列是
OTc1YzExZDY2ZTE1MTVmYmJmNWNhNDRhNWMxZGIzZDk0NmM3OGE4NDU2N2JkYTJmZDJlYWI0ODRhNjlhNTdiYg==
而 header 对于相同的样本响应 header 总是带有
W+D70ded8u5DG7P4BcG0u2etvAqQZvxz70Q4OXh0vlY=
我以为我弄错了 JSOn body 所以我尝试了 json_encode 和 json_decode 的所有组合但没有任何帮助,我的哈希值永远不匹配.
我也尝试过使用 $webhookContent = json_decode(file_get_contents('php://input'), true);
来存储 POST body 但结果是空的($_POST 也不起作用)。
除了收到JSON之外,我是不是做错了什么?
作为测试响应的body出现的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"}
如果有助于了解我哪里出错了,提供了一个示例,但它在 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")));
我的错误是没有将 $raw_output
parameter of the hash_hmac()
function 指定为 true
。
raw_output
When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.
因此,由于我没有将 $raw_output
指定为 true
,我得到的是 hexits
而不是原始二进制输出,它看起来像这样:975c11d66e1515fbbf5ca44a5c1db3d946c78a84567bda2fd2eab484a69a57bb
。
编辑:这里的答案是
<?php
$sig_ver_sha = hash_hmac('sha256', $webhookContent, $secret, true);
$sig_ver_hash = base64_encode( $sig_ver_sha );
?>