Sockets TCP通信中的消息划分

Sockets TCP通信中的消息划分,sockets,security,tcp,Sockets,Security,Tcp,我是网络新手,尤其是TCP(我一直在用UDP愚弄一点,但仅此而已)。 我正在开发一个基于在两个端点之间交换消息的简单协议。这些消息需要经过认证,所以我实现了一个加密层来解决这个问题。然而,虽然UDP对数据包有一个合理的定义,它构成了一次可以传输的最小单元,但TCP协议(据我所知)是完全面向流的 现在,这让我有点困惑。在交换信息时,我如何知道一个从哪里开始,另一个从哪里结束?原则上,我可以传递固定长度的消息,或者首先在某个报头中传递每条消息的大小。然而,这可能会受到攻击:当然,不可能歪曲或确定通信

我是网络新手,尤其是TCP(我一直在用UDP愚弄一点,但仅此而已)。 我正在开发一个基于在两个端点之间交换消息的简单协议。这些消息需要经过认证,所以我实现了一个加密层来解决这个问题。然而,虽然UDP对数据包有一个合理的定义,它构成了一次可以传输的最小单元,但TCP协议(据我所知)是完全面向流的

现在,这让我有点困惑。在交换信息时,我如何知道一个从哪里开始,另一个从哪里结束?原则上,我可以传递固定长度的消息,或者首先在某个报头中传递每条消息的大小。然而,这可能会受到攻击:当然,不可能歪曲或确定通信内容,但上述技术只需在中间添加一个字节就可以很容易地破坏我的通信。

假设我需要传输一条1234567字节长的消息。首先,我将4个字节与一个表示消息大小的整数进行通信。可以然后我开始发送实际的消息。该消息被分成几个数据包,分别接收。现在,攻击者只是发送一个额外的数据包,假装它是对话的一部分。它可能只有一个字节长:这完全破坏了我实现的任何同步机制!该消息在中间有一个虚假字节,并且没有成功解码。不仅如此,第一条消息的最后一个字节破坏了第二条消息的对齐,以此类推:连接被破坏,并且发生了一次简单的攻击!这种攻击到底有多大的可能性和可行性

所以我想知道:一次可以传输的最大数据单位是多少?我知道发送呼叫与接收呼叫并不对应:消息可以分为不同的块。如何以某种方式将数据包分组,以便知道它们是打包在一起的?有没有一种方法可以定义一个更高级别的消息,该消息将被重新构造并对齐在一起,并触发一个对类receive函数的调用?如果没有,我可以找到什么其他解决方案来保持我的通信重新对齐,即使在攻击者在场的情况下

现在,攻击者只是发送一个额外的数据包,假装它是对话的一部分。它可能只有一个字节长:这完全破坏了我实现的任何同步机制

阻止这种注入问题通过保护流来解决。创建一个加密流并通过该流发送数据包

当然,加密流本身也有这个问题;它的消息可能被破坏。但是这些消息有安全的完整性检查。检测到问题,可以断开连接并重新建立连接以重新同步

此外,一些固定长度的同步/帧位序列可以在消息之间使用:一些特定的位模式。如果该模式偶然出现在消息内部,这无关紧要,因为我们只有在出现问题时(接收到损坏的消息)才会专门查找该模式,否则我们会跳过该序列。如果接收到损坏的消息,我们将接收字节,直到看到同步模式,并假设随后的内容是消息的开始(长度后跟有效负载)。如果失败了,我们重复这个过程。当我们收到正确的消息时,我们会回复对等方,对等方会重新传输我们没有得到的任何信息

这种攻击到底有多大的可能性和可行性

TCP连接由四项标识:源和目标IP以及源和目标端口号。攻击者必须在这四个标识符中伪造一个与您的流相匹配的数据包,并将该数据包通过攻击者和接收机器之间的所有路由器和防火墙。攻击者还必须在TCP序列号方面处于正确的大概位置


基本上,攻击者C几乎不可能攻击网络上距离C较远的端点A和B。假源IP将在C到达目的地之前很久被拒绝。作为一项内部工作(包括恶意软件),它更为合理:C接近A和B。

基本上,很难控制操作系统将流划分为TCP数据包的方式(定义TCP协议的RFC声明,TCP堆栈应允许客户端使用推送功能强制其发送缓冲数据,但未定义应生成多少数据包。毕竟,攻击者可以修改其中任何数据包)

这些TCP数据包在通过网络的过程中会被分成更多的IP片段(这可以通过一个“不分段”的IP标志来选择——但是这个标志会导致数据包根本没有被传递)

我认为您的问题不是将数据包引入流协议,而是如何保护它

IPSec在您的场景中可能非常有用,因为它在网络层上运行

它为发送的每个数据包提供完整性,因此会检测到线路上的任何修改,并丢弃无效数据包。在TCP的情况下,丢弃的数据包会自动重新传输

(几乎)所有的事情都是由操作系统自动完成的——所以你不需要担心(而且在这样做时会出错)

保密性也可以得到保证(具有不重新发明轮子的相同优点)

IPSec应该为您提供一个可靠的传输协议ontop,您可以使用任何喜欢的帧格式

另一种选择是在TCP会话之上使用SSL/TLS,这不太可靠(因为它确实会在完整性错误时关闭整个连接)。

与您所选择的非常相关