crypto.createHmac 失败,字符串如下"face_url":"https//" '



我在用Node.js.验证cryptocreateHmac创建的字符串时遇到问题

我做了一些测试,首先是在PHP中——一切都很好,但我在Node.js:中找不到正确的方法

PHP代码:

$jsonData = '"face_url":"https://"';
echo($jsonData);
echo("n");
$client_secret = 'kqm6FksaIT';
echo hash_hmac("sha256", $jsonData, $client_secret);

结果:

"face_url":"https://"
34a4eb09a639c9b80713158ae89e7e8311586e6e6d76e09967f4e42a24759b3e

对于Node.js,我对字符串的解释有一个问题:

var crypto = require('crypto');
var str = '"face_url":"https://"';
console.log(str);
//OK
var buf1 = crypto.createHmac('sha256','kqm6FksaIT').update(str);
var v = buf1.digest('hex');
console.log(v);
//END

结果:

"face_url":"https://"
eb502c4711a6d926eeec7830ff34e021ed62c91e574f383f6534fdd30857a907
=> FAIL.

正如你所看到的,字符串的解释是不同的"face_url":"https://"** VS **"face_url":"https://"**

我尝试了很多东西,Buffer。从base64,utf8,JSON.stringify,JSON.parse,但我找不到解决方案。

如果您尝试使用另一个字符串,如:'"face_url":"https"',则OK。结果相同。

我尝试验证Netatmo POST数据包中接收到的密钥,该数据包包含:"face_url":"https://netatmocameraimage.blob.core

您可以在这里找到netatmo-webhook在PHP中的实现:https://github.com/Netatmo/Netatmo-API-PHP/blob/master/Examples/Webhook_Server_Example.php

反射后,代码之间唯一的区别是对request.body.的解释

在PHP中,它似乎是纯文本的。Nodejs以JSON格式解析请求。。。

在这个假设之后,我今天早上用NodeJS做了一些测试,我用以下选项配置了express服务器:

var express = require('express');
var crypto = require('crypto');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.text({type:"*/*"}));

之后,字符串以这些著名的"/":

console.log结果:,";face_url":"https://netatmocameraimage.blob.core.windows.net/production/

瞧!HMAC现在是正确的!

NETATMO中的HMAC是根据brut文本计算的,而不是根据JSON计算的!

在PHP代码中,只有转义序列\'单引号表达式中被识别,在所有其他情况下,反斜杠被解释为字面反斜杠,即/被解释为后面跟着字面斜杠的字面反斜杠(请参阅此处,第节单引号(。这解释了PHP代码的输出:

$jsonData = '"face_url":"https://"';
...
Output:
"face_url":"https://"
34a4eb09a639c9b80713158ae89e7e8311586e6e6d76e09967f4e42a24759b3e

在JavaScript中,对于不表示转义序列的字符,会忽略反斜杠(请参阅此处的最后一段(,即/等效于文字斜杠。这解释了JavaScript代码的输出:

var str = '"face_url":"https://"';
...
Output:
"face_url":"https://"
eb502c4711a6d926eeec7830ff34e021ed62c91e574f383f6534fdd30857a907

因此,为了让JavaScript代码给出与PHP相同的结果,必须屏蔽反斜杠:

var str = '"face_url":"https:\/\/"'; 
...
Output:
"face_url":"https://"
34a4eb09a639c9b80713158ae89e7e8311586e6e6d76e09967f4e42a24759b3e 

假定带有/的字符串是带有json_encode()的PHP中JSON序列化的结果,默认情况下会转义/,即将其转换为/,另请参阅此处。在JavaScript中,/被简单地序列化为/。请注意,在PHP中,可以使用JSON_UNESCAPED_SLASHES禁用/的转义,另请参阅此处。

相关内容

最新更新