UDP安全性和识别传入数据

时间:2010-05-11 04:33:10

标签: python security encryption cryptography udp

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

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

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

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

6 个答案:

答案 0 :(得分:4)

一种解决方案是使用TCP,因为它不受开放互联网欺骗源地址的影响,因为three-way-handshakeMore information为什么TCP源地址欺骗不可能)。如果您仍想使用UDP,则可以进行模拟三次握手以开始连接。然后可以将会话ID添加到每个UDP分组。这将使连接开销增加2个数据包和每个数据包几个位,但与tcp相比,您仍将从UDP的速度获得剩余的会话。

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

你不应该重新发明风暴,但如果你因某种原因需要加密UDP,你应该使用像RC4-drop1024这样的流密码,或者更好地使用OFB Mode中的AES 256之类的分组密码。与其他加密模式相比,这将节省带宽,因为它们可以舍入到最大的块大小。

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

答案 1 :(得分:1)

您可以查看HMAC

<强>百科:

  

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

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

答案 2 :(得分:0)

如果您确实需要验证特定用户是否为特定用户,那么您需要在用户签署其消息时使用某种形式的加密。这可以很快完成,因为用户只需要生成其消息的哈希值,然后对哈希值进行签名(加密)。

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

答案 3 :(得分:0)

DTLS可能是最佳解决方案,但是,它似乎非常记录不足。我一直在寻找一个类似的解决方案,我已经看到OpenSSL的DTLS实现的所有参考建议你需要深入研究OpenSSL示例和找出如何使用它的源代码...对我来说,这意味着当我尝试设置它时,我将犯下10个严重的安全错误。另外,我不相信pyOpenSSL liberary会导出这个功能。

我一直在考虑的另一种选择是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)需要大约300ms。但是,在OpenSSL中使用BigNumber支持的SRP算法的C ++中的直接实现只用了2ms。因此,如果您打算采用这种方式,我强烈建议您使用algorihim的C / C ++实现来生成代码。否则,您可能每秒只能处理几次登录。

答案 4 :(得分:0)

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

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

  • 非常不安全 - 网络上的任何人只有在至少具有对线路的读取权限时才能欺骗有效的请求/响应。 (被动MITM)(即具有浏览器cookie的http可访问论坛)

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

  • 安全 - 即使有完全访问权限,也无法欺骗请求/响应 线。 (即https可访问的电子商务网站)

对于网络游戏,非常不安全的解决方案实际上可以接受(这将是我的选择)它不需要加密。只是你的应用程序UDP数据包格式中的一个字段,在游戏期间会随处运送某种随机的,不可思议的会话标识符。

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

对于游戏而言,UDP是一个巨大的好处,因为如果丢包,您不希望IP堆栈浪费时间重新传输失效状态 - 您希望发送新状态。使用UDP时,有许多聪明的方案,例如未确认的帧(世界详细信息,如果它们丢失则无关紧要)和重复状态数据的统计方法,以抵消可预测的观察到的丢包级别。

在一天结束时,我会建议去非常不安全或有点不安全/只有DTLS完整性。

答案 5 :(得分:0)

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

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

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