如何在加密的有效负载前添加未加密的成帧头(使用Sslstream)

时间:2013-10-21 15:23:36

标签: c# tcp networkstream sslstream ice

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

ICE-TCP RFC说:

“ICE要求代理解复用STUN和应用层流量,因为它们出现在同一端口上。这种解复用在[RFC5245]中描述,并使用魔术cookie和消息的其他字段完成 面向流的传输引入了另一种皱纹,因为它们需要一种方法来构建连接,以便可以提取应用程序和STUN数据包,以区分STUN数据包和应用层流量。
因此,使用ICE的TCP媒体流使用RFC 4571(http://tools.ietf.org/html/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加密之外,我必须将未加密的标头写入流中。

目前我的应用程序使用围绕NetworkStream的SslStream类,我从TCPClient获取它。我的第一个目的是将帧标头写入NetworkStream,然后将加密的应用程序数据写入SslStream。经过一番研究后我发现了这个:

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

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

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

提前致谢。

祝你好运

马库斯

1 个答案:

答案 0 :(得分:2)

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

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

只要您将直接写入NetworkStream的任何内容保留在连接任一侧的SslStream上,SslStream将继续正常运行。

实际上,您将在单个流中复用两个字节流。其中一个字节流将是SSL流,另一个将是您的其他流。只要连接的两端都知道何时在两个流之间切换,你应该没问题。