UDP安全性与识别来往数据

8 投票
6 回答
5004 浏览
提问于 2025-04-15 22:34

我正在开发一个应用程序,使用UDP来传输和接收信息。现在我遇到的问题是安全性。目前,我是通过IP地址和socketid来判断哪些数据属于谁。

但是,我发现有人可以轻松伪造他们的IP地址,然后以特定的IP发送数据。这看起来是个不安全的方法。那么,我该如何识别哪些数据属于哪些用户呢?比如说,有10个用户连接,每个用户都有特定的数据。服务器需要将用户的数据与我们收到的数据进行匹配。

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

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

6 个回答

0

如果你真的需要确认某个用户就是那个用户,那么你就得用一些加密的方法,让用户给他们的信息签名。这个过程其实挺简单的,用户只需要对他们的信息生成一个哈希值,然后对这个哈希值进行签名(加密)就可以了。

不过对于你的游戏应用来说,可能不需要太担心这个问题。大多数网络服务提供商(ISP)不会允许用户伪造IP地址,所以你只需要关注那些在NAT后面的用户,也就是可能有多个用户使用同一个IP地址的情况。在这种情况下,以及一般情况下,你可以比较安全地通过一个包含IP地址和UDP端口的组合来识别独特的用户。

1

你可以查看一下HMAC

维基百科:

在密码学中,HMAC(基于哈希的消息认证码)是一种特定的构造方法,用于计算消息认证码(MAC)。它结合了一个加密哈希函数和一个秘密密钥。和其他的MAC一样,它可以同时验证数据的完整性和消息的真实性。

每个客户端都需要获取一个唯一的令牌,只有他们自己知道。每次他们发送消息时,都会根据这个令牌和消息内容生成一个哈希值,并将这个哈希值和消息一起发送出去。这样,你就可以验证这条消息是来自特定的客户端。

4

一种解决方案是使用TCP,因为它能有效防止在开放的互联网中伪造源地址。这是因为TCP有一个叫做三次握手的过程(更多信息说明了为什么TCP的源地址伪造是不可能的)。如果你还是想用UDP,可以模拟一个三次握手来开始连接。然后可以在每个UDP数据包中添加一个会话ID。这样会增加2个数据包和每个数据包几个比特的连接开销,但在会话的其余时间里,你仍然能享受到UDP的速度,相比TCP来说。

不过,无论是使用TCP还是UDP作为传输层,仍然会面临其他攻击,比如嗅探中间人攻击,这些攻击可能通过ARP伪造DNS缓存中毒来实现。另一个问题是,如果攻击者和玩家在同一个局域网内,比如无线网络或其他广播网络,那么你可以接收到所有流量,而不管源地址或目标地址是什么,这时伪造三次握手就变得可能了(而且HMAC也无能为力!)。最好的解决方案是使用SSL/TLS作为你的传输层,这样可以解决所有这些问题。

你不需要重新发明轮子,但如果你出于某种原因需要加密UDP,应该使用像RC4-drop1024这样的流密码,或者更好的是使用像AES 256这样的块密码,采用OFB模式。这样可以节省带宽,因为其他加密模式会向上取整到最大的块大小。

编辑: 根据Marts的评论,关于(数据报传输层安全)DTLS,我做了一些调查,发现有一个官方RFC,并且它得到了OpenSSL的支持,应该可以通过pyOpenSSL库来使用。我建议使用RC4-SHA密码套件来减少开销,这个套件在SSL 3.0(最新版本)中得到了支持。不过,DTLS可能会比TCP有更多的开销(延迟!)。

撰写回答