2016-09-29 144 views
0

我有一个中央Web服务器(Node.js),并且还有几个客户端计算机(也运行Node)。这些客户端将把数据推送到Web服务器,因此,为了安全起见,客户端将首先向主服务器注册 - 生成它自己的唯一SSL私钥/公钥并将公钥存储在服务器上。Node.js:使用唯一公钥对客户端进行身份验证(与Github SSH密钥身份验证类似)

现在,注册后,客户端每次尝试与服务器通信时,都需要显示其公钥(?)来验证自己。

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

我该如何让客户将他们的证书与他们的数据一起“呈现”?我看过几个软件包,比如client-certificate-auth,但我认为这不会对我的用例有所帮助。

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

+0

您是否打算使用微妙的网络加密API?我想我明白你想要什么。我可以为你写一个例子...你希望javascript中生成的私钥在客户端保密,公钥在服务器上安全地发送和存储... – TylerY86

+0

在认证过程中,客户端说公钥是由一个唯一的标识符标记。然后,服务器发出一个挑战消息,使用用户的公钥加密消息。用户用他的私钥解密该消息,然后正确响应。这提供* no *安全性,您必须通过已建立的SSL连接执行此操作。它是传统cookie和会话令牌的替代品,它只是不同的,更难的,而不是更好的。私钥永远不会到达服务器。 – TylerY86

回答

1

如果您要走此路径,请使用Subtle Crypto API。最有可能的是,你不应该这样做。

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

鉴别过程中,客户说什么这是公钥是与它相关的一些唯一标识符的公钥,例如ID或通用名称或用户名称。

然后,服务器发出挑战消息,并使用客户端的公钥公钥加密。

用户用他的私钥解密消息,然后用正确的解密响应进行响应。

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

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

私钥永远不会随时到达服务器。客户端不使用私钥进行加密,这不是公钥密码学的工作原理。

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

要进行数字签名的挑战,服务器会发送一个质询字符串给客户端,客户端使用它的私钥并响应服务器签署的挑战,然后服务器验证使用公钥签名。 公钥必须是签名的一部分,并且服务器必须知道信任公钥,因此它必须能够快速查找它。

另一种选择是依靠用户建立自己的客户端证书的知识,在这种情况下,Paul的答案中提到的passport-client-cert可以处理该问题。

1

我强烈建议您自己不要这样做,如果您没有正确实施,会出现很多错误。

那说,这种东西工程建筑是以“目前的客户端的公钥”,而是让客户端加密的东西用自己的私钥和加密的数据发送到服务器,然后一路用客户的公钥解密。如果能够这样做的话,它就知道客户端就是它声称的客户端(理论上,它的可靠性可能会因您的密钥空间而异)。

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

正常情况下,此握手仅用于交换客户端可用于加密其所有流量的会话密钥,因为CPU上的对称密钥加密通常比PKI更容易。老实说,虽然我只是抓了表面。您可能会更好地了解PassportJS为策略提供哪些策略并选择其中之一。也许passport-api-keypassport-client-cert将做你所需要的。

+0

我认为你倒退了PKI挑战...客户端不用私钥加密。 – TylerY86

+0

您可能正在考虑数字签名挑战。 – TylerY86

+0

从技术上讲,在这种情况下称为签名,但该过程仍然用于加密一些已知字节。 – Paul