1

I have a server that is listening for clients with a TcpListener.BeginAcceptTcpClient() method. When a client connects, the EndAcceptTcpClient method gives me the TcpClient object and then I call that client stream's NetworkStream.BeginRead() to listen for data transmitted from the client.

Everything works well until a client (who is expecting the server to support SSL) attempts to connect to the (insecure) server. The data that is retrieved from the NetworkStream.BeginRead() callback when the client attempts to do the SSL handshaking, is gibberish of course, but what is the proper way to detect this handshake after reading the data vs a "normal" message from a client?

Does an SSL handshake have a known header/signature identifier that I could check for by looking at the first few bytes of received messages to distiguish the difference between a normal message and the SSL handshake? From inspection the bytes received, it looks like it may be ASCII 0x16 0x03 0x01 0x00 (a.k.a <SYN><ETX><SOH><NUL>).

If there is a known header, is there a response I can send to the client to tell it the authentication failed (via the NetworkStream)?

4

2 に答える 2

1

SSL プロトコルに関する情報をいくつか見つけました (refs 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" メッセージ)で始まるメッセージを探すことができます。

拒否メッセージについては、(2 バイト バージョン) に0x15 0x?? 0x?? 0x00 0x02 0x02 0x28変換されたものを送信できるようです<NACK>。これは、2 バイト長のメッセージ、致命的なアラート、「ハンドシェイクに失敗しました」3です。

于 2013-03-20T17:44:55.867 に答える
0

SSL / TLSクライアントは、ClientHelloメッセージを送信してハンドシェイクを開始します

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;

ここで、表示されているのはその前です。これは、プロトコルTLS 1.0()を使用したハンドシェイクメッセージ( )のレコードレイヤーです。その後に長さを続け、次に「Client Hello」とバージョン(おそらく異なる:クライアントによってサポートされる最高のもの)を続ける必要があります。0x160x03010x01

実用的な観点からは、Wiresharkを使用して実際のパケット(HTTPSなど)を確認する価値があります。このページにはいくつかのサンプルキャプチャと例があります(ただし、実行しようとしていることのためにトラフィックを解読する必要はありません)。

于 2013-03-20T17:43:34.673 に答える