3

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

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

第一部分:

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

我的想法:

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

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

我的担忧:

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

第二部分:

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

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

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

哦,顺便说一句。我不需要关于公钥/私钥、握手等的解释。知道我会在商业产品中使用这个算法(许可方面)可能很重要。

4

2 回答 2

4

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

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

由于 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. 为每个用户使用唯一的、预分配的私钥,您可以使用传入会话进行验证。如果他们没有以其他方式获得该密钥,这将使 mitm 攻击更加困难,但非自动生成的私钥通常难以与用户友好性相结合。您在如何分发它们(该死,我如何在那里处理 mim?)、如何将它们存储给用户(哦,他使用笔记本电脑、iPhone 和 iPad)、如果丢失时如何恢复它们、. ..
  2. Make sure that all traffic is initiated by the client and encrypted immediately with the server's public key. This is easier as you don't have to distribute a private key. However, a hacker can still replace your server's public key with it's own key, but it's a lot harder and if done right almost comes down to installing a virus on the client computer.
  3. Do some sanity checks in your client application. For example, make sure you're connecting to a known pool of server IP's, check if the DNS query is correct, etc etc. It's far from fail-safe but it are simple verification that will discourage potential hackers.
  4. Educate your users. This is what many banks do (at least where I live), let them do a regular anti-virus check, only use trusted WiFi-networks, verify the DNS servers, ... . Of course some things are harder to teach then others, but a little common sense gets you a long way.

Oh and finally I do actually want to comment on the UDP part: are you really really sure? Because almost everything of this scheme and even a lot more is covered by TLS, which is integrated in boost asio. If your traffic is that low-rate I can hardly imagine it's an application that needs the advantages that UDP offers, unless you want to secure voip, which is done already, don't reinvent the wheel.

于 2012-10-01T07:06:56.797 回答
0

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

几个google关键词:密码证书;公钥密码学;SSL;TSL;中间人攻击

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

也有不需要填充的流密码,但它们的发展不如分组密码先进。密码学专家认为它们中的大多数还不是非常强大和可靠。

于 2012-10-01T06:34:07.290 回答