节点Hmac身份验证

And*_*iga 2 hmac node.js

我对身份验证过程的理解。主机创建一个secret和一个public api key。客户端借助密钥对有效负载进行加密,这就是签名。然后将其公钥,有效负载,签名发送给主机。

客户实例

主机检查是否允许公钥进行操作,并根据客户端的公钥获取机密。在秘密的帮助下,主机解密签名并将其与有效负载进行比较。

  • 以上过程描述正确吗?
  • 如何解密签名并将其与有效负载进行比较?
  • 还是我应该以与客户端相同的方式对其进行加密,然后进行比较?
  • 这两个步骤updateNode Docs到底做了什么digest

客户:

  authenticate: (self)->
    payload = 'AUTH' + moment()
    signature = crypto.createHmac('sha384', WEBSOCKET_SECRET)
      .update(payload)
      .digest('hex')

    data = {
      event: 'auth',
      apiKey: WEBSOCKET_KEY,
      authSig: signature,
      authPayload: payload
    }
    self.send self, data
Run Code Online (Sandbox Code Playgroud)

服务器:

hmac = crypto.createHmac('sha384', WEBSOCKET_SECRET)
hmac.on 'readable', () ->
  data = hmac.read()
  if (data)
    console.log data, data.toString('utf-8')


# hmac.write(authPayload)
hmac.write(signature)
hmac.end()
Run Code Online (Sandbox Code Playgroud)

当前服务器端解决方案

  authenticate: (authPublicKey, authSignature, authPayload)->
    signature = crypto.createHmac('sha384', WEBSOCKET_SECRET)
      .update(authPayload)
      .digest('hex')

    return authSignature == signature
Run Code Online (Sandbox Code Playgroud)

Dap*_*que 5

HMAC不用于加密/解密,仅用于身份验证和数据完整性检查。

客户用他的秘密密钥发送他的有效载荷,他的pk和他的有效载荷的hmac。服务器用他的pk检索用户,用检索到的sk重新计算hmac,然后检查计算出的hmac是否等于检索到的hmac。

客户有一个公共密钥和一个秘密密钥:

var str        = payload_string;
var public_key = pk;
var secret_key = sk;

var hmac = crypto.createHmac('sha384', sk).update(str).digest('hex');

request.post({uri:..., json: { hmac, public_key, payload: str }, function(err, response, body) {
   console.log(body);
});
Run Code Online (Sandbox Code Playgroud)

在服务器上:

exports.... = function(req, res)
{
   var hmac = req.body.hmac;
   var pk = req.body.public_key;
   var payload  = req.body.payload;


   // retrieve authorized user
   User.findOne({ pk }, function(err, user) {
      if(err || !user){
        return res.status(403).json({error:"Invalid user"});
      }

      // recompute hmac
      var compute_hmac= crypto.createHmac('sha384', user.sk).update(payload).digest('hex');

      // check hmac
      if(compute_hmac != hmac) {
        return res.status(403).json({error:"Security check failed"});
      }
      // do stg
      return res.status(200).json({success:"ok"});
    });
  }
Run Code Online (Sandbox Code Playgroud)


小智 5

这些线路容易受到定时攻击:

if(compute_hmac != hmac) {

return authSignature == signature
Run Code Online (Sandbox Code Playgroud)

最好使用:

crypto.timingSafeEqual(a, b)
Run Code Online (Sandbox Code Playgroud)