【问题标题】:UDP security and identifying incoming dataUDP 安全性和识别传入数据
【发布时间】:2011-02-17 23:34:37
【问题描述】:

我一直在创建一个使用 UDP 传输和接收信息的应用程序。我遇到的问题是安全性。现在我正在使用 IP/socketid 来确定哪些数据属于谁。

但是,我一直在阅读有关人们如何简单地欺骗他们的 IP,然后将数据作为特定 IP 发送的文章。所以这似乎是错误的做法(不安全)。那么我还想如何识别哪些数据属于哪些用户呢?例如,您连接了 10 个用户,所有用户都有特定的数据。服务器需要将用户数据与我们收到的数据进行匹配。

我能看到的唯一方法是使用某种客户端/服务器密钥系统并加密数据。我很好奇其他应用程序(或游戏,因为这就是这个应用程序)如何确保他们的数据是真实的。还有一个事实是,加密的处理时间比未加密的要长得多。虽然我不确定它会对性能产生多大影响。

任何信息将不胜感激。谢谢。

【问题讨论】:

  • 您可能需要考虑某种隧道,例如 SSH 或 IPSEC。您要通过身份验证来断言谁是谁的唯一方法。
  • @jathanism 滞后呢? ssl/tls/dtls 出了什么问题?
  • SSL/TLS/DTLS 没有问题,我只是提供替代方案。特别是 SSL 需要签名证书,除非您使用自签名证书,否则除了加密之外,您真的不会买太多。

标签: python security encryption cryptography udp


【解决方案1】:

一种解决方案是使用 TCP,因为它不会在开放的 Internet 上欺骗源地址,因为 three-way-handshakeMore information 说明为什么 TCP 源地址欺骗不可能。)。如果您仍想使用 UDP,您可以模拟三向握手来开始连接。然后可以将会话 ID 添加到每个 UDP 数据包。这将增加 2 个数据包和每个数据包几位的连接开销,但是与 tcp 相比,在会话的其余部分中,您仍然可以从 UDP 的速度中获益。

但是,使用 TCP 或 UDP 作为transport layer 仍然会使您容易受到其他攻击,例如使用arp spoofingdns cache poisingSniffingMan in The Middle 攻击。另一个问题是,如果攻击者和游戏玩家都在同一个本地局域网上,例如无线网络或另一个广播网络,那么无论源/目标地址如何,您都可以接收流量,并且只有这样欺骗三向握手是否成为可能(并且 hmac 也无济于事!)。最好的解决方案是使用 SSL/TLS 作为解决所有这些问题的传输层。

您不应该重蹈覆辙,但如果出于某种原因需要加密 UDP,您应该使用像 RC4-drop1024 这样的流密码,或者在 OFB Mode 中使用像 AES 256 这样的块密码更好。与其他加密模式相比,这将节省带宽,因为它们会四舍五入到最大的块大小。

编辑: 根据 Marts 对(数据报传输层安全性)DTLS 的评论,我进行了一些挖掘,发现有一个 official RFC 并且它受 OpenSSL 支持,应该使用 pyOpenSSL 库公开。我建议使用 RC4-SHA 密码套件来减少开销,该套件受 SSL 3.0(最新)支持。但是 DTLS 可能会比 TCP 有更多的开销(LAG!)。

【讨论】:

  • 对于 UDP,解决方案是使用 DTLS,而不是直接使用芯片重新发明轮子。考虑到原始问题,原始发布者可能不会在第一时间就正确。
  • @Mart Oruaas Cool 我不知道 DTLS,如果它是由 TLS 构建的,你应该能够协商使用带宽的流密码。
  • 我已经研究过 TCP,它似乎是阻止我所问的一个不错的选择。然而,我读过的许多文章都劝阻它远离游戏。从技术上讲,会话 ID 也不能被欺骗吗?只是发送增加 # 的数据包,直到我们得到有效的回复?我会研究密码,因为它们看起来很有趣。对其他人来说需要注意的一件事是必须以某种方式读取和使用来自客户端的数据。因此散列数据将不起作用。在数据前面添加一个哈希会使数据大小增加到无法忍受的程度。
  • TCP 不比 UDP 更不受欺骗。欺骗 TCP 数据包可能更难,但正如您所说,这绝不是不可能的。欺骗是 IP 协议中的一个固有问题,并不是任何一种主要传输协议所独有的。
  • 我并没有试图抹黑你所说的,TCP 不受欺骗并且 TCP 源地址欺骗是不可能的。这些事情实际上是可能的,甚至在您链接的文章中也是如此。建立欺骗性的 TCP 连接是不可能的,但在正确的情况下仍然不是不可能的。防止欺骗的保护在很大程度上依赖于数据包过滤,不幸的是,许多管理员仍然错误地执行了此操作。 (symantec.com/connect/articles/ip-spoofing-introduction 是该主题的一个很好的概述)。我只是想澄清一下。 :)
【解决方案2】:

你可以看HMAC

维基百科:

在密码学中,HMAC(基于哈希的 消息验证码),是一个 计算的具体结构 消息验证码 (MAC) 涉及加密哈希 与秘密相结合的功能 钥匙。与任何 MAC 一样,它可以用于 同时验证两个数据 完整性和真实性 消息。

每个客户都需要获得一个只有他们知道的唯一令牌。他们发送的每条消息,他们都会根据令牌和消息进行哈希处理,并将其与消息本身一起发送。然后您可以验证消息是否来自特定客户端。

【讨论】:

  • HMAC 是为了数据的完整性,我没明白它是如何防止 IP 欺骗的?
  • +1:会话开始时的质询/响应,然后每条消息都会附加一个签名(数据+会话密钥)
  • @Berkay:欺骗者几乎不可能“知道”客户端的种子(用于计算 HMAC),因此服务器可以安全地丢弃所有没有正 HMAC 的消息。
  • 无论客户的 IP 地址是被什么欺骗了?你会为每个客户分配不同的密钥吗?然后是使用 IPSEC。
  • @Robert 为了计算哈希串通,您必须知道整个消息。如果您知道 HMAC 中使用的密钥,那么您可以伪造生成的散列并且生成冲突无济于事。此外,在 md5() 攻击中,攻击者必须能够控制消息的前缀。如果密钥是预先添加的,那么 md5() 哈希冲突是不可能的。请阅读 Bruce Schnieier 的“实用密码学”。
【解决方案3】:

如果您绝对需要验证特定用户是否是特定用户,那么您需要使用某种形式的加密来让用户签署他们的消息。这可以很快完成,因为用户只需要生成他们消息的散列,然后对散列进行签名(加密)。

对于您的游戏应用程序,您可能不需要担心这一点。大多数 ISP 不会允许他们的用户欺骗 IP 地址,因此您只需要担心 NAT 后面的用户,其中您可能有多个用户从同一个 IP 地址运行。在这种情况下,以及一般情况下,您可以根据包含 ip 地址和 UDP 端口的元组相当安全地识别唯一用户。

【讨论】:

  • udp 的重点是轻量级。与不受欺骗的 TCP 相比,使用加密会显着增加协议的开销。
  • 我不同意。 UDP 的重点是实时而不是可靠。在游戏环境中,您不太关心可靠性,而更关心低延迟。整理数据包的开销主要是由于网络往返时间而不是 TCP 堆栈中的额外代码。此外,我推测在数据报上计算哈希并为其计算签名与平均互联网延迟相比不会引入瓶颈。
  • 与 TCP 相比,使用带有 udp 的流密码可以节省一些带宽。但是,总的来说,我认为这种有目的的安全系统正在滥用资源。特别是开发人员实现这个有目的的安全系统的资源。 SSL/TLS 是解决此问题的免费且最安全的解决方案。
【解决方案4】:

DTLS 可能是最佳解决方案,但是它似乎非常没有记录。一段时间以来,我一直在寻找类似的解决方案,并且我看到的所有关于 OpenSSL 的 DTLS 实现的参考资料表明,您需要深入研究 OpenSSL 示例和源代码以了解如何使用它。 .. 对我来说,这意味着我在尝试设置它时会犯 10 个严重的安全错误。另外,我不相信 pyOpenSSL 库会导出此功能。

我一直在考虑的另一种选择是Secure Remote Password Protocol。此解决方案的优点是它为您提供了强大的相互身份验证(根据文档与 Kerberos 的安全性相当),并且在您的情况下同样重要的是,它为两端提供了可用于加密的共享会话密钥.

给定共享密钥,每个数据包可能包含AES256_CBC( <random starter block for CBC><user-id><sequence_number><application data> ) 如果解密成功提供预期的用户ID,则数据包被验证为来自您的用户,并且序列号可用于避免重放攻击。

SRP 的一个缺点是,在 Python 中,数字处理非常缓慢。我将演示 Python 代码修改为更实用的代码,发现执行单个客户端-服务器 SRP 交换(2Ghz CPU)大约需要 300 毫秒。然而,使用 OpenSSL 中的 BigNumber 支持在 C++ 中直接实现 SRP 算法只需要 2 毫秒。因此,如果您打算走这条路,我强烈建议您将算法的 C/C++ 实现用于生产代码。否则,您可能每秒只能处理几次登录。

【讨论】:

  • 这个安全系统与我所说的非常接近,除了你遗漏了最重要的部分,因为所有这些都增加了 LAG。攻击是停止欺骗,而不是缓解丢弃。
  • @Rook:不是真的。这是一种使用标准协议进行身份验证和密钥交换来保护 UDP 通信的特定方法。这种方法可以防止欺骗和窃听,并且在初始身份验证握手之外不会产生延迟。
【解决方案5】:

我将其分为四个安全级别。

  • 极度不安全 - 网络上的任何人都可以利用普遍可用的先验知识来欺骗有效的请求/响应。 (即系统日志)

  • 非常不安全 - 网络上的任何人都可以欺骗有效的请求/响应,前提是他们至少具有对网络的读取权限。 (被动 MITM)(即带有浏览器 cookie 的 http 可访问论坛)

  • 有些不安全 - 网络中的任何人都可以欺骗有效的请求/响应,前提是他们可以读取并更改线路(活动 MITM)(即具有自签名证书的 https 站点)

    李>
  • 安全 - 即使完全访问 金属丝。 (即 https 可访问的电子商务网站)

对于互联网游戏,非常不安全的解决方案实际上可能是可以接受的(这是我的选择)它不需要加密。只是您的应用程序 UDP 数据包格式中的一个字段,其中包含在游戏期间传输的某种随机的几乎无法猜测的会话标识符。

有些不安全需要一点加密,但不需要信任/PKI/PSK 来阻止安全解决方案的 Active-MITM。如果数据负载不敏感,则有些不安全,您可以使用具有 (TCP) TLS/ (UDP) DTLS 的仅完整性密码来减少客户端和服务器的处理开销和延迟。

对于游戏来说,UDP 是一个巨大的好处,因为如果出现数据包丢失,您不希望 IP 堆栈浪费时间重新传输陈旧状态 - 您希望发送新状态。使用 UDP 有许多巧妙的方案,例如非确认帧(世界细节,如果它们丢失就无关紧要)和复制重要状态数据以应对可预测的观察到的丢包水平的统计方法。

最后,我建议只使用非常不安全或有点不安全的 /w DTLS 完整性。

【讨论】:

    【解决方案6】:

    我会查看 Garage Games 网络库。它是用 C++ 编写的并使用 UDP。它专为低延迟而设计,被认为是最好的游戏之一。

    如果我没记错的话,他们实际上会计算玩家在客户端和服务器端的可能位置。它将在许多方面做到这一点,以确保数据的完整性。它还会对客户端软件进行 crc 检查,并与服务器软件进行比较以确保它们匹配。

    我不确定您是否可以再单独获得许可,因此您可能必须获得游戏引擎许可(100 美元)。它至少可以让您对经过验证的游戏 UDP 方法有所了解。另一种可能性是研究 PyGame 网络代码。它可能已经解决了您面临的问题。

    【讨论】:

      猜你喜欢
      • 2015-05-20
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2014-05-22
      • 2013-02-05
      • 2015-06-30
      • 2015-09-04
      • 2011-08-27
      相关资源
      最近更新 更多