4

我正在创建一个基于异步套接字的客户端服务器通信,我的客户端会将用户名和密码发送到服务器,然后服务器将重播帐户是否有效,所以我想保护这个步骤,所以没有人可以记录对话并保留将其发送给我的客户以实现对秘密数据的非法访问

[问题{简化}] 如何安全地向服务器验证客户端...?

[注意] 我知道 SSL,但我买不起证书,所以我需要一个免费的替代方案来提供我的客户端和服务器之间的安全通信。

4

4 回答 4

13

与往常一样,最安全的密码是服务器不知道且永远不会传输的密码。所以你可以做的是:

  • 在服务器上,存储用户名、随机加盐(“帐户加盐”)和加盐密码的安全散列(“服务器共享密钥”)。
  • 登录时,第一步让客户端只传输用户名(不是秘密)
  • 服务器应回复帐户 salt(非机密)和随机生成的会话 salt(非机密)。重要的是,服务器生成会话盐。
  • 在客户端上,使用帐户 salt 对密码进行加盐并对其进行哈希处理(将此保留为“客户端共享机密”),然后使用会话 salt 对结果进行加盐并再次对其进行哈希处理。将此作为身份验证令牌(非机密)传输
  • 在服务器上,从您的数据库中获取加盐散列,用会话盐加盐并散列它 - 如果这与身份验证令牌匹配,则连接已通过身份验证。(客户端通过服务器身份验证)

  • 如果您想向客户端额外验证服务器,请重复该过程:客户端生成一个盐,服务器通过对存储的秘密进行加盐/散列处理从中创建令牌。

  • 如果您想验证单个请求(不仅是连接),请使用共享密钥对其进行加盐并对其进行哈希处理,并将其作为每个请求的身份验证字段发送。由于在一个有效的登录服务器共享密钥和客户端共享密钥是相同的,双方应该得出相同的结果,从而验证身份验证字段。

在此处输入图像描述

于 2012-09-03T22:51:28.717 回答
4

我通常会告诉人们,如果他们发现自己在做加密,他们就是在制造安全问题。:) 你错过边缘情况的可能性很大。我建议依靠已经存在并得到严格保护的东西。

如果您使用托管套接字,则有一个流类版本可以为您执行加密 (NegotiateStream)。我建议从那里开始,看看它是否可以满足您的需求,而无需您自己发明。

于 2012-09-03T22:54:28.383 回答
0

您可以使用公钥和对称密钥的组合来保护身份验证。

首先发送一个公钥,让客户端发送加密后的身份验证数据。如果数据有效,您可以让客户端生成自己的公钥,并通过彼此的公钥相互发送对称密钥。

像这样的东西应该工作。

于 2012-09-03T23:32:07.813 回答
0

我知道这是几年前发布的,但我想我现在会在这里添加我自己的两美分。在过去的几年里,情况发生了变化。这可能对其他人有所帮助。

我不想从 Eugen 那里拿走任何东西,出色的工作。

加密客户端和服务器之间的流量的最佳方式仍然是使用 SSL/TLS。您现在可以从https://letsencrypt.org/获得免费许可证。

听起来您已经弄清楚了 SSL,所以我将使用您从上述链接获得的免费证书插入

祝你好运 - 安德鲁

于 2017-01-30T01:08:30.823 回答