套接字认证和加密

4 c++ sockets authentication encryption

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

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

第一部分:

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

我的想法:

  1. 创建一个容器,存储所有允许连接的客户端的所有地址(登录成功后)
  2. 创建一个存储所有会话 ID 的容器(会话 ID 将随每个数据包一起发送)

其他想法值得赞赏(特别是如果它们已经被使用)

我的担忧:

  1. 有人可以更改数据包发送者的地址吗?(我认为是的)
  2. 会话 ID 可能会被嗅探出来。(我记得有些大公司有这个问题)

第二部分:

尽管如此,我还是必须加密我的数据包。在 (2) 的情况下,加密可以与会话 ID 相关,以便只有来自用户的数据包可以使用与该客户端相对应的正确会话密钥进行解密(类似 AES,仅提供示例)。

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

  1. 哪种算法适合这个(RSA 似乎有点太慢)?
  2. 这个算法将如何工作?(只有一个非常简短的摘要,但希望提供更多信息)
  3. 它会加密数据包,使其与原始数据包一样大,还是会更大,以便我必须在服务器端编写某种缓存机制来组装这些数据包?

哦,顺便说一句。我不需要对公钥/私钥、握手等进行解释。了解我将在商业产品中使用此算法(许可方面)可能很重要。

Kil*_*nDS 5

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

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

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

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

这实际上是通用解决方案,您的第一个解决方案只是一个特定的实现,您使用源 IP 作为会话 ID。如果您担心会话 ID 管理,只需使用UUID,会话 ID 之间发生冲突的可能性非常低。或者,当使用公钥/私钥加密时,您可以使用用户的公钥作为会话 ID。

这里的一个重要部分是如何协商会话 ID。您可能想让用户选择,您可能想使用“特殊”会话ID(例如0)来让服务器选择。什么是最好的取决于您的应用程序。

有人可以更改数据包发送者的地址吗?(我认为是的)

当然,这被称为中间人攻击(如果对传输中的数据包进行攻击)或IP 地址欺骗(如果发送带有虚假 IP 的数据包),并且对于大多数最终用户来说是无法检测到的。尽管许多网络都对此采取了保护措施,例如使用反向路径转发

会话 ID 可能会被嗅探出来。(我记得有些大公司有这个问题)

如果加密:也许(见下文)。如果不加密:当然。

关于您的加密问题的整个部分:

一般来说,您的方向是正确的,您通常希望对常规流量使用对称密钥加密方案。AES 是一个不错的选择,但还有其他选择,请做一些研究。

但是,您在设置加密时遇到问题。一般来说,您需要安全地获取双方的加密密钥,而不会让人们嗅探它们。您可以尝试通过航空邮件发送密钥,但我怀疑大多数用户会发现这种方式很方便,甚至并不安全。

这就是非对称密钥加密方案的用武之地。您通常会使用 RSA 之类的东西来协商初始连接(会话 ID、加密密钥,可能还有一些记账,...),并让对称密钥接管实际流量。一种流行的方案是Diffie-Hellman 密钥交换,但同样还有更多这样的方案。

话虽如此,您可以很好地保护您的频道,但中间人攻击始终是一个问题。事实证明,您实际上无能为力来真正防止这种情况,因为您无法控制其中一方(客户端),如果它是一台受感染的机器,那么所有的赌注都会失败:

  1. 为每个用户使用唯一的预分发私钥,您可以通过传入会话进行验证。如果中间人攻击不能以其他方式获取该密钥,这将使中间人攻击变得更加困难,但非自动生成的私钥通常很难与用户友好性结合起来。您在如何分发它们(该死,我该如何处理那里的 mim ?)、如何将它们存储在用户处(哦,他使用笔记本电脑、iPhone 和 iPad)、如何在丢失时恢复它们等方面遇到了麻烦。 ..
  2. 确保所有流量均由客户端发起并立即使用服务器的公钥进行加密。这更容易,因为您不必分发私钥。然而,黑客仍然可以用自己的密钥替换服务器的公钥,但这要困难得多,如果做得正确,几乎可以归结为在客户端计算机上安装病毒。
  3. 在您的客户端应用程序中进行一些健全性检查。例如,确保您连接到已知的服务器 IP 池、检查 DNS 查询是否正确等等。这远非万无一失,但它是简单的验证,可以阻止潜在的黑客。
  4. 教育您的用户。这是许多银行所做的(至少在我住的地方),让他们定期进行防病毒检查,只使用受信任的 WiFi 网络,验证 DNS 服务器,......。当然,有些事情比其他事情更难教,但一点常识会让你走得更远。

哦,最后我确实想对 UDP 部分发表评论:你真的确定吗?因为该方案的几乎所有内容甚至更多内容都由TLS涵盖,它集成在boost asio中。如果您的流量如此低速,我很难想象这是一个需要 UDP 提供的优势的应用程序,除非您想保护 voip,这已经完成了,不要重新发明轮子。