2013-03-20 55 views
1

我有一个服务器正在倾听客户的方法TcpListener.BeginAcceptTcpClient()。当客户端连接时,EndAcceptTcpClient方法为我提供了TcpClient对象,然后我调用该客户端流的NetworkStream.BeginRead()来侦听从客户端传输的数据。检测SslStream(客户端)连接尝试不安全的服务器(NetworkStream)?

一切正常,直到客户端(期待服务器支持SSL)尝试连接到(不安全)服务器。当客户端尝试执行SSL握手时,从NetworkStream.BeginRead()回调中检索到的数据当然是乱码,但在读取数据之后检测此握手的正确方法与来自客户端的“正常”消息相比如何?

SSL握手是否有一个已知的标头/签名标识符,我可以通过查看接收到的消息的前几个字节来检查普通消息和SSL握手之间的差异来检查吗?从检查收到的字节看起来它可能是ASCII 0x16 0x03 0x01 0x00(又名<SYN><ETX><SOH><NUL>)。

如果有一个已知的标题,是否有我可以发送给客户端的响应,告诉它认证失败(通过NetworkStream)?

回答

1

我发现对SSL协议的一些信息(参12),而且是我可以找一个标准的头:

从IBM参考网站2

Byte 0  = SSL record type = 22 (SSL3_RT_HANDSHAKE) 
Bytes 1-2  = SSL version (major/minor) 
Bytes 3-4  = Length of data in the record (excluding the header itself). 
Byte 5  = Handshake type 
Bytes 6-8  = Length of data to follow in this record 
Bytes 9-n  = Command-specific data 

所以我可以查找以0x16 [0x?? 0x??] [0x?? 0x??] 0x01(SSL“Client Hello”消息)开头的消息。

对于拒绝消息,它看起来像我可以给0x15 0x?? 0x?? 0x00 0x02 0x02 0x28其转换为<NACK>,(2字节版本),这是一个2字节长的消息,致命的警告,“握手失败” 3

0

SSL/TLS客户端将通过发送Client Hello消息来发起握手。

在XDR符号,这就是:

struct { 
     ProtocolVersion client_version; 
     Random random; 
     SessionID session_id; 
     CipherSuite cipher_suites<2..2^16-2>; 
     CompressionMethod compression_methods<1..2^8-1>; 
     select (extensions_present) { 
      case false: 
       struct {}; 
      case true: 
       Extension extensions<0..2^16-1>; 
     }; 
    } ClientHello; 

在这里,你看到的是在此之前:它是record layer,与协议TLS 1.0(0x0301)握手消息(0x16)。它后面应该有一个长度,然后0x01代表“客户端Hello”和一个版本(可能不同:客户端支持的最高值)。

从实际的角度来看,使用Wireshark值得关注实际的数据包(例如HTTPS)。有一些示例捕获和示例on this page(尽管您不需要解释您正在尝试执行的操作)。

相关问题