套接字认证和加密

时间:2012-09-29 14:52:41

标签: c++ sockets authentication encryption

这包括多个问题,但由于它们有些相关,我想将它们一起发布。

我在做什么: 我正在编写一个服务器 - 客户端应用程序,用户必须登录才能与服务器通信。现在我正在使用udp(是的,我确定我想使用udp)进行一些小修改。

第一部分:

存储用户连接的最佳方式是什么?

我的想法:

  1. 创建一个容器,存储允许连接的所有客户端的所有地址(成功登录后)
  2. 创建一个存储所有会话ID的容器(会话ID将随每个数据包一起发送)
  3. 赞赏的其他想法(特别是如果它们已被使用)

    我的担忧:

    1. 有人可以更改数据包发件人的地址吗? (我假设是)
    2. 会话ID可能会被嗅出。 (我记得有一些大公司名称有这个问题)
    3. 第二部分:

      然而,我必须加密我的数据包。在(2)的情况下,加密可能与会话ID有关,因此只有来自用户的数据包才能使用与该客户端相对应的正确会话密钥进行解密(AES就像提供示例一样)。

      这需要一个快速的适当算法(可能有30-50个数据包,每个客户端每秒发送256个字节)

      1. 哪种算法适合此(RSA似乎有点太慢)?
      2. 这个算法将如何运作? (只有非常简短的摘要,但需要了解更多信息的来源)
      3. 它会加密数据包,使其与原始数据包一样大,还是会更大,以便我必须在服务器端编写某种缓存机制来组装这些数据包?
      4. 哦,顺便说一下。我不需要对公钥/私钥,握手等进行解释。了解我会在商业产品中使用此算法(许可方式)可能很重要。

2 个答案:

答案 0 :(得分:4)

如果没有特定的应用程序,这很难回答,但我会尝试给出一些通用的提示:

  

创建一个容器,存储所有客户端的所有地址   允许连接(成功登录后)

这根本不会起作用,因为NAT,遗憾地仍在使用,实际上甚至因为IPv4耗尽而增加。你至少需要src-ip + src-port。即便如此,考虑到移动用户,您可能永远不会想要将IP用作会话ID。普通的智能手机将非常容易地在蜂窝和WiFi网络之间切换,最常见的是导致IP堆栈的完全重启,因此无法将新流量与先前的流量相关联。这可能是也可能不是问题,但除非你能控制IP地址,否则我绝不会使用这种方法。

  

创建一个存储所有会话ID的容器(会话ID将被发送   每个包)

这实际上是通用解决方案,您的第一个解决方案只是一个特定的实现,您使用source-ip作为会话ID。如果您关注会话ID管理,只需使用UUID's,会话ID之间的冲突几率就会非常低。或者,当使用公钥/私钥加密时,您可以使用用户的公钥作为会话ID。

这里的一个重要部分是如何协商会话ID。你可能想让用户选择,你可能想要一个特殊的' session-id(例如0)让服务器选择。什么是最好的取决于您的申请。

  

有人可以更改数据包发件人的地址吗? (我假设   是)

当然,这被称为man-in-the-middle attack(如果在传输中的数据包上完成)或ip address spoofing(如果发送带有虚假IP的数据包),并且对于大多数最终用户来说是不可检测的。虽然许多网络都有此保护,例如使用Reverse Path Forwarding

  

会话ID可能会被嗤之以鼻。 (我记得一些大公司的名字   有这个问题)

如果加密:也许(见后文)。如果没有加密:当然。

关于加密问题的全部内容:

通常,您处于正确的轨道上,您通常希望对常规流量使用对称密钥加密方案。 AES是一个不错的选择,但还有其他的,做一些研究。

但是,您在设置加密时遇到问题。一般情况下,您需要安全地获取双方的加密密钥,而无需人们嗅探它们。您可以尝试通过航空邮件发送密钥,但我怀疑大多数用户会发现用户友好,甚至不是非常安全。

非对称密钥加密方案的用武之地。您通常会使用类似RSA的东西来协商初始连接(会话ID,加密密钥,可能是某些会计,......)并让对称密钥占用实际交通。一个流行的方案是Diffie-Hellman key exchange,但是那里还有更多的方案。

所有人都说你可以很好地保护你的频道,但是中间人攻击始终是一个问题。事实证明,你实际上很少能够做到这一点,因为你无法控制其中一方(客户端),如果它是受感染的机器,所有赌注都将关闭:

  1. 为每个用户使用唯一的预分发私钥,您可以对传入的会话进行验证。如果他们没有以其他方式获得该密钥,这将使得mitm攻击更加困难,但是非自动生成的私钥通常很难与用户友好性相结合。如何分发它们会遇到麻烦(darn,我如何在那里处理mim?),如何将它们存储在用户(哦,他使用笔记本电脑,iPhone和iPad),如果丢失它们如何恢复它们。 ..
  2. 确保所有流量都由客户端启动,并立即使用服务器的公钥加密。由于您不必分发私钥,因此这更容易。但是,黑客仍然可以使用自己的密钥替换服务器的公钥,但是如果做得好,几乎可以归结为在客户端计算机上安装病毒。
  3. 在您的客户端应用程序中进行一些健全性检查。例如,请确保您已连接到已知的服务器IP池,检查DNS查询是否正确等等。它远非故障安全,但它是简单的验证将阻止潜在的黑客。
  4. 教育您的用户。这是许多银行所做的事情(至少我居住的地方),让他们定期进行反病毒检查,只使用可信赖的WiFi网络,验证DNS服务器,......当然有些事情比其他事情更难教,但是一点常识会让你走得很远。
  5. 哦,最后我确实想对UDP部分发表评论:你真的很确定吗?因为TLS涵盖了此方案的几乎所有内容甚至更多内容,boost asio已集成在{{3}}中。如果您的流量是低流量我很难想象它是一个需要UDP提供优势的应用程序,除非您想要保护已经完成的voip,否则不要重新发明轮子。

答案 1 :(得分:0)

所有加密系统都需要加密密钥。必须在加密传输开始之前交换此密钥。在加密之前通过未加密的网络连接发送此密钥时,攻击者可能会拦截此密钥并嗅探连接。当攻击者能够更改密钥时,他也可以操纵传输。防止这种情况的唯一方法是不通过网络交换密钥,而是使用不同的介质或使用受信任机构签名的加密证书。

一些谷歌关键字: 加密证书;公钥密码学; SSL; TSL;中间人攻击

大多数加密算法(如AES)都是分组密码。这意味着它们以固定大小的块(如256或512字节)加密消息。当消息不适合块大小时,它将在加密前用零填充。当您发送大量短消息时,这可能会产生大量开销。

还有一些不需要填充的流密码,但它们的开发并不像分组密码那样先进。密码学专家认为大多数都不是非常强大和可靠。