如何比较NodeJS

时间:2018-02-17 15:56:12

标签: node.js dropbox dropbox-api sha256 hmac

我正在尝试使用Dropbox的API,我通过webhooks成功向我发送提醒,但现在我想在每次向我发送提醒时验证签名。

从dropbox的文档中,他们写道:

"每个通知请求都将包含一个名为X-Dropbox-Signature的标头,其中包含请求正文的HMAC-SHA256签名,使用您的app secret作为签名密钥。这样,您的应用就可以验证通知是否真的来自Dropbox。"

所以我成功捕获了该签名,并使用内置加密模块的NodeJS尝试使用HMAC SHA256创建自己的签名,然后将我的签名与Dropbox发送给我的签名进行比较。

这是我的代码:

  var sign = req.get("X-Dropbox-Signature");
  console.log(sign);
  var hmac = crypto.createHmac(algorithm, secret);
  hmac.update(JSON.stringify(req.body));
  hash = hmac.digest('hex');
  console.log(hash);

算法只是' sha256' 而秘密是我从我的Dropbox应用页面获得的秘密密钥。 我必须使用JSON.stringify(req.body),因为req.body是一个对象而hmac.update是一个字符串。我想知道这是我的错误来自哪里?

我控制台记录了来自dropbox的签名,然后我控制台记录我使用hmac创建的签名,但它是一个不同的签名。

对我可能做错的任何建议?

2 个答案:

答案 0 :(得分:2)

格雷格是对的。您需要使用原始正文请求来检查消息的成分。以下代码使用body-Json库来提取原始主体。

 var bodyParser =  require("body-parser");

 app.use(bodyParser.json({verify:function(req,res,buf){req.rawBody=buf}}))

然后是post方法:

app.post('/webhooks', function(req, res) {

 const retrievedSignature = req.get("X-header-Integrity")
 //send this body string for validation with secret
 const bodyString = new Buffer(req.rawBody, 'utf8')

  let check = integrityCheck(retrievedSignature, bodyString, "secret")

});

答案 1 :(得分:1)

以下代码段是使用Node的本机HTTP服务器计算请求正文的HMAC的基本示例。在Express中间件中可以非常容易地(并且更干净地)应用相同的概念。

const http = require('http');
const crypto = require('crypto');

const APP_SECRET = 'prozr59vkis4454';
const REQUEST_BODY = '{"list_folder": {"accounts": ["dbid:AABL4QRrY7tB9viLgPUqmjkzE6Fe5ujlnlE"]}, "delta": {"users": [22575230]}}';
const SIGNATURE = 'aa2508fb90b757aa382edb0815c7f7df0ce1943c53f28fae96e1dc9eb7f677b1';

const server = http
  .createServer((req, res) => {
    const header = req.headers['x-dropbox-signature'];
    const hmac = crypto.createHmac('sha256', APP_SECRET);
    req.on('data', (chunk) => {
      hmac.update(chunk);
    })
      .on('end', () => {
        const hash = hmac.digest('hex');
        console.log('signature from header:', header);
        console.log('calculated signature: ', hash);
        res.writeHead(204);
        res.end();
      });
  })
  .listen(1313, () => {
    const request = http.request({
      host: 'localhost',
      port: 1313,
      method: 'POST',
    }, () => {
      server.close();
    });

    request.setHeader('x-dropbox-signature', SIGNATURE);

    request.write(REQUEST_BODY);
    request.end();
  });