【问题标题】:Client Server Authentication客户端服务器身份验证
【发布时间】:2012-08-28 14:17:09
【问题描述】:

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

[The Question {Simplified}] 如何安全地向服务器验证客户端...?

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

【问题讨论】:

  • 如何托管服务器应用程序? IIS?
  • 它是一个套接字侦听器...不使用 IIS。
  • 我似乎记得那个发明了自己的服务器安全的人对客户有一个傻瓜。

标签: c# sockets authentication client communication


【解决方案1】:

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

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

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

  • 1234563由于在一个有效的登录服务器共享密钥和客户端共享密钥是相同的,双方应该得出相同的结果,从而验证身份验证字段。

【讨论】:

  • 也许我看错了,但我认为 OP 是在询问连接安全性。就是说,你说的都是好话,但我还是宁愿把这个问题外包出去,让一个现有的、已知安全的库来为我处理。
  • II 没看错,问题是:“如何安全地向服务器验证客户端” - 这是通过我的建议实现的。当然,我没有实现连接机密性(我不认为它被要求)。至于使用库:我明白这一点,但我不是 100% 相信:如果不破坏目的,任何使用的库都需要被信任——如果你像 OP 那样排除 SSL,这可能是一个相当大的挑战.
  • 这归结为我的赔率。你认为 OP 会像微软在基本 CLR 实现中那样做吗?我很怀疑。
  • @EricFleischman 说得好,+1 先生!我没有立场(或愿意)判断 OP 的潜在实施。我在建议的过程中只使用非常简单的步骤(连接和散列)的原因,这恰好是我做这类事情的标准方式(缺少 TLS 或朋友),是为了更有可能做出正确的实现。当然,我已经抽象成一个库供我在很多语言中使用,以免每次都重新发明轮子。就我个人而言,这让我比使用无法验证的 3rd 方库更舒服。口味不同。
  • 正如我所说:口味不同。我无意说服你甚至争论你。对您而言,信任第三方库效果更好,对我而言,信任我或我的开发人员自己的代码(或他们或我审查的代码)效果更好。两种说法都有其优点,我是最后一个反对你的。
【解决方案2】:

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

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

【讨论】:

  • OTOH 将加密和安全外包给第三方库(甚至可能是您无法在源代码级别验证的库)可能需要特殊级别的信任。
  • 公平。我将首先尝试使用 MSFT 堆栈中的内置加密库(根据应用程序管理首选)。这些都得到了很好的保护,并被其他 MSFT 产品使用。他们受到了极大的安全关注。
  • NegotiateStream 足够安全,因此我可以依靠它来处理我的所有数据。[注意] 我没有任何人在没有合法许可的情况下访问我的服务器,因为数据库将包含重要信息。我想确保客户端只连接到我的服务器
  • 我觉得没有资格权威地回答这个问题。这取决于您的需求以及您如何使用 NegotiateStream。我可以说这是一个很好的起点,而不是建立自己的起点。 :)
  • 我的程序将被公开发布,我非常担心我的程序会被破解,因为它的数据库将包含重要信息,因此您必须向我提供最佳身份验证方法,以确保我的程序至少有 90%客户可以免受任何黑客攻击
【解决方案3】:

您可以结合使用公钥和对称密钥来确保身份验证的安全。

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

类似的东西应该可以。

【讨论】:

    【解决方案4】:

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

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

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

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

    祝你好运, - 安德鲁

    【讨论】:

      猜你喜欢
      • 2011-11-04
      • 2012-04-15
      • 1970-01-01
      • 2016-07-25
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多