我在用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
禁用/
的转义,另请参阅此处。