Node.js:使用唯一公钥验证客户端(类似于Github SSH密钥验证)

时间:2016-09-29 03:11:12

标签: javascript node.js authentication ssl ssl-certificate

我有一个中央网络服务器(Node.js),还有几台客户端机器(也运行Node)。这些客户端将把数据推送到Web服务器,因此,为了安全起见,客户端最初将向主服务器注册 - 生成它自己唯一的SSL私钥/公钥并将公钥存储在服务器上。

现在,在注册之后,每次客户端尝试与服务器通信时,都需要提供它的公钥(?)来验证自身。

我想了解如何解决这个问题。我应该将客户端的所有公钥的内容存储在常规数据库集合中吗?

如何让客户“提供”证书及其数据?我见过一些像client-certificate-auth这样的软件包,但我不认为这对我的用例有帮助。

编辑:我忘了提及,我将通过HTTPS(端口443)进行通信,所以我认为它会处理实际的安全部分。我只是想确保没有流氓的,未注册的客户端使用pub / private加密/ SSL证书将数据推送到服务器。

2 个答案:

答案 0 :(得分:2)

如果您沿着这条路走下去,请使用Subtle Crypto API。最有可能的是,你不应该这样做。

您希望javascript中生成的私钥在客户端保密,并且公钥在服务器上安全地发送和存储。

在身份验证过程中,客户端通过与其关联的公钥(例如,公共密钥)的某些唯一标识符来说明它的公钥是什么。 id或通用名称或用户名。

然后,服务器使用客户端公钥加密消息有效负载发出质询。

用户使用私钥解密邮件,然后使用正确的解密回复进行回复。

这不提供任何安全性,您必须通过已建立的SSL连接执行此操作。

它是传统cookie和会话令牌的替代品,它只是不同,更难,而不是更好。

私钥永远不会到达服务器。客户端不使用它的私钥加密,这不是公钥加密的工作方式。

然而,它可以发送数字签名,服务器可以验证。这是唯一标识符的替代方案;确保你指定一个真实且足够长的随机数来签名。

要执行数字签名质询,服务器会向客户端发送质询字符串,客户端使用私钥签署质询并响应服务器,然后服务器验证使用公钥的签名。 公钥必须是签名的一部分,服务器必须知道信任公钥,因此它必须有办法查看快点。

另一种选择是依靠用户的知识来设置他们自己的客户端证书,在这种情况下,保罗的答案中提到的passport-client-cert可以处理。

答案 1 :(得分:1)

我强烈建议不要自己这样做,如果你没有正确实现它,你可能会遇到很多问题。

也就是说,这种方式在架构上的工作方式是来“呈现客户端的公钥”,而是让客户端使用其私钥加密某些内容并将该加密数据发送到服务器,然后使用客户端的公钥解密。如果它能够做到这一点,它知道客户端是它声称的客户端(理论上;它的可靠性可能因密钥空间而异)。

客户端加密了什么?嗯,这很大程度上取决于(再​​次)你想要多么安全/偏执。一种方法(准kerberos)将是客户端向服务器发送请求以加密信息。这是通过SSL完成的,因此客户端可以确保服务器是它所说的人(并且可以检查CA等,如果需要)。传回来的是一些包含随机值,到期值以及某种类型的随机数的数据。它也由服务器存储,以便稍后查询,当然也可以按时逐出。客户端通常会使用该确切对象(可能是JSON对象)并使用其私钥对其进行加密,然后将其发送回服务器以访问某个登录端点。正如我之前所说,服务器将根据客户端的ID检查其对象的存储位置,并进行比较以查看这两个对象是否相同。如果是,那么它可以接受客户就是它所说的那样。

通常,此握手仅用于交换客户端可用于加密其所有流量的会话密钥,因为CPU上的对称密钥加密通常比PKI更容易。

但是,老实说,我只是表面上看了。你可能会更好地看看PassportJS为战略提供什么,并选择其中一个。也许passport-api-keypassport-client-cert可以满足您的需求。