1

我正在编写一个需要安全登录的 C# .NET 应用程序。我已经拥有了在数据库中使用哈希和盐安全存储密码的必要功能,但是,我现在正从测试阶段开始。在开发之前(登录没有优先级),我只是直接连接到我的数据库。我知道这对于生产应用程序来说是不安全的,因为您公然将数据库凭据存储在代码中。相反,我选择创建一个简单的异步 TCP 套接字服务器,它侦听用户名,从数据库发送回 salt,然后客户端对输入的密码进行哈希处理(salt 临时存储在本地)并将其发送回服务器。然后服务器检查它们是否匹配;如果用户签出,则返回 true/false。

我已经进行了一些研究并研究了加密 TCP 连接,但是,这真的有必要吗,因为密码已经被散列了?还是有更好的整体做事方式?我愿意接受有关客户端/服务器架构应该如何工作的建议。登录在整个应用程序中并没有扮演那么重要的角色,但它将是生产级的,我不想把设计不佳的应用程序放在那里。

4

3 回答 3

3

然后客户端对输入的密码进行哈希处理(盐暂时存储在本地)并将其发送回服务器。然后服务器检查它们是否匹配;如果用户签出,则返回 true/false。

我已经做了一些研究并研究了加密 TCP 连接,但是,这真的有必要吗,因为密码已经被散列了?

所谓的“密码”并不重要,唯一重要的是服务器将接受什么作为有效凭据。如果您输入密码并且服务器在那里对其进行哈希处理(正如@Christian Stewart 在评论中建议的那样),那么您的密码就是您的凭据。如果您自己对密码进行加盐和哈希处理,并将结果发送到服务器,那么此结果将成为您的凭据。拦截它就像拦截原始密码+盐一样。

所以,是的,在通过它发送凭据之前,您还必须加密您的连接。SslStreamClass似乎是最简单的方法(检查底部的示例代码,用于服务器和客户端),它同时支持服务器身份验证和可选的客户端身份验证(如果您还想限制哪些机器将有权访问登录服务器)。

于 2013-03-08T22:59:21.260 回答
2

1) 如果您要发送敏感数据,保护它的最简单方法是使用 SSL。如果这是一个内部项目,您可以生成自己的证书。此外,与您的 IT 人员讨论这是否是一个潜在问题。如果将其部署在正确配置的有线 Intranet 情况下,用户将无法看到彼此的流量。

2)您对盐和哈希的使用搞砸了,它不再解决它本来应该解决的问题。散列和加盐旨在使数据库的内容对攻击者没有帮助。这不是这里的情况,因为存储在数据库中的是服务器接受的作为身份验证令牌的内容。必须在服务器上进行散列,以便服务器通过网络接受的值不可逆(散列)和唯一(盐)转换为出现在用户存储中的值。现在确实,被攻击者无法反转它以获取用户的密码(即他们输入到您的客户端的密码)——这很好——但如果攻击者知道数据库中的值,他们就不需要密码。

3) 戴上攻击者的帽子。如果您看到您的身份验证交换发生,您是否能够在不知道秘密的情况下登录?是的,您只需发送客户端发送的最后一件事。所以这个频道应该是加密的。

4)如果可以避免,请不要编写自己的加密货币。如果可以避免,甚至不要管理用户。人们不想在他们使用的每个应用程序中管理用户和组——我说这是以前犯过这个错误的人。您可以使用 LDAP 或域身份验证之类的吗?

于 2013-03-09T00:14:13.897 回答
1

使用诸如魔兽世界使用的免费SRP之类的协议,有一些方法可以在不传输密码的情况下通过服务器对用户进行身份验证。

SRP 将根据各方对密码的了解执行一系列挑战来验证用户身份,而不会将有关密码的敏感信息泄露给网络。

仍然使用 WoW 作为参考,有一些开源模拟器,例如TrinityCore,它为您提供了 SRP 的可靠示例。

于 2013-03-08T23:07:29.607 回答