我正在通过SCTP-rfc进行TLS支持,在那里我可以看到规范引用了TLS握手必须在通过传输启动消息传输之前在每个双向流上进行。
5.连接和双向流
TLS通过在双向流上建立连接来利用双向流。这意味着关联的连接数量受到双向流数量的限制。TLS握手协议分别用于每个双向流。
因此,如果我打开了5个SCTP双向流,这是否意味着我必须分别对5个双向流中的每一个进行密钥交换、证书验证等?
我之所以这么问,是因为我觉得很奇怪,协议设计希望开发人员在每个流上重复TLS握手,即使打开的套接字只有一个,并且在打开的每个流上都进行相同的握手。
我还尝试编写了一个基于SCTP的TLS示例代码,其中TLS握手是在流0上完成的,并且我能够在所有5个流上进行数据传输。
那么,这是一些规范必须要做的事情吗?如果我只在一个流上进行握手,并在所有相关流上进行数据传输,会发生什么?是否存在相关的安全漏洞?
请有人启发我一下。
Meta:这并不是一个真正的编程问题。它可能更适合安全性。SX,它广泛地涵盖了SSL/TLS,以及DTLS,尽管我还记得不起SCTP。
TLS假设并需要TCP提供的服务,即(单个)按顺序的八位位组流,其中数据按顺序传递,而不会丢失、复制或重新排序,除非连接失败,在这种情况下,数据传递完全停止并可检测。记录格式和完整性检查算法(HMAC或AEAD)依赖于此。如果您通过流A发送TLS的"有线"格式的一部分,并通过流B发送另一部分,并且B上的部分在A上的部分之前到达,或者A被传递但B丢失,反之亦然,TLS将丢失bigtime。
有两种可能的解决方案:
-
不要使用完全握手TLS(以及之前的SSL)包括会话"消耗",该会话使用双方缓存的上一次握手的结果(主要是协商的主密钥),通常有一个小时或一天的时间限制。这避免了通常代价高昂的公钥加密(密钥加密或协议和证书验证),也避免了可能耗时的带外证书检查(无标记OCSP或CRL或替代方案)。它只使用1.5个交换的"bbreviated">握手:ClientHello、ServerHello加CCS和Finished、CCS和Finish,所有这些都很短,除了可能ClientHello。
rfc3436第8.2节、第8.3节、第8.4节中的示例使用了(并隐含地建议)这一点。
有一种可选的会话恢复形式,没有太多使用,它在多对一(或多对少)的情况下降低了服务器的负载,在这种情况下,服务器不会实际缓存会话信息,而是向客户端提供加密/密封的"票证",客户端会将其发送回。
-
使用DTLS还有一个变体协议,数据报与TLS1.1匹配的TLS rfc4347或与TLS1.2匹配的rfc6347,它自己进行分段(仅握手)和序列编号。这并不需要比UDP提供的更好的传输,即任何传递的数据报都与发送的数据报相对应,但数据报可能会丢失、重复或排列错误。因此,它将在SCTP上工作,尽管让两个协议级别都增加测序开销会有一些效率低下的地方。