【问题标题】:How to add unencrypted framing header in front of encrypted payload (using Sslstream)如何在加密的有效载荷前添加未加密的帧头(使用 Sslstream)
【发布时间】:2013-10-30 04:22:42
【问题描述】:

我正忙于使用 C# 和 .NET Framework 4.5 实现 ICE-TCP (RFC 6544 https://www.rfc-editor.org/rfc/rfc6544)。但是,我面临一个与协议分层相关的非常棘手的问题,如下所示。

ICE-TCP RFC 说:

„ICE 需要代理来解复用 STUN 和应用层流量,因为它们出现在同一个端口上。这种解复用在 [RFC5245] 中进行了描述,并使用魔法 cookie 和消息的其他字段完成。
面向流的传输引入了另一个问题,因为它们需要一种方法来构建连接,以便可以提取应用程序和 STUN 数据包,以便将 STUN 数据包与应用层流量区分开来。
因此,使用 ICE 的 TCP 媒体流使用 RFC 4571 (https://www.rfc-editor.org/rfc/rfc4571#section-2) 中提供的基本帧,即使应用层协议不是 RTP。“

取景方式如下:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 ---------------------------------------------------------------
|             LENGTH            |  RTP or RTCP packet ...       |
 ---------------------------------------------------------------

我还想在我的实现中使用 TLS,ICE-TCP RFC 说:

„当使用传输层安全性 (TLS) 或数据报传输层安全性 (DTLS) 时,它们也在 RFC 4571 成帧垫片上运行,而 STUN 在 (D)TLS 连接之外运行。生成的 ICE TCP 协议栈如图 1 所示,左侧有 (D)TLS,右侧没有。”

ICE TCP 栈最终看起来像这样:

                   +----------+
                   |          |
                   |    App   |
        +----------+----------+     +----------+----------+
        |          |          |     |          |          |
        |   STUN   |  (D)TLS  |     |   STUN   |    App   |
        +----------+----------+     +----------+----------+
        |                     |     |                     |
        |      RFC 4571       |     |      RFC 4571       |
        +---------------------+     +---------------------+
        |                     |     |                     |
        |         TCP         |     |         TCP         |
        +---------------------+     +---------------------+
        |                     |     |                     |
        |         IP          |     |         IP          |
        +---------------------+     +---------------------+

所以我对图的左侧很感兴趣。该图表明帧头在 TLS 加密之外,我必须将未加密的头写入流中。

目前,我的应用程序使用 SslStream 类包裹在我从 TCPClient 获得的 NetworkStream 周围。我的第一个意图是将帧头写入 NetworkStream,然后将加密的应用程序数据写入 SslStream。经过一番研究,我发现了这一点:

“在 AuthenticateAsClient/Server 之后,您的连接将受到 SSL 保护。然后不要调用 Socket 或 NetworkStream 方法:这会破坏 SslStream。“ 来源:C# Sockets and SslStreams

所以一旦 SSL 连接建立,我就无法写入 NetworkStream。

我的问题是:有没有办法在 TCP (NetworkStream) 和 TLS (SslStream) 之间“放置”标头?

提前致谢。

最好的问候

马库斯

【问题讨论】:

  • 可以直接写入网络流,会绕过SSL流。您引用的答案只是警告您,如果不格外小心,在 SSL 流之外写入会导致问题。既然您打算添加框架,那将不是问题。
  • 谢谢你,William,但你能解释得更详细些吗?如果我将帧头直接写入网络流,这意味着我是否在 SSL 流之外写入?因此,如果没有额外的照顾,这可能会导致问题。这种额外的照顾意味着什么?那么为什么我添加框架时不会有问题呢?

标签: c# tcp networkstream sslstream ice


【解决方案1】:

SslStream 实例将自身分层在NetworkStream 实例之上。您写入 SSL 流的任何数据都由 SSL 流处理,然后将其生成的任何数据写入 NetworkStream 实例。

如果您保留对NetworkStream 的引用,您可以根据需要直接读取或写入NetworkStream,绕过SSL 流。

只要您避免直接写入NetworkStream 的任何内容被连接任一侧的SslStream 读取,SslStream 将继续正常运行。

实际上,您将在一个流中复用两个字节流。这些字节流之一将是 SSL 流,另一个将是您的其他流。只要连接的两端都知道何时在两个流之间切换,就可以了。

【讨论】:

  • 非常感谢。我明天试试。如果可以的话,我会投票,但需要更多的声誉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 2019-04-17
  • 2022-12-17
  • 1970-01-01
相关资源
最近更新 更多