Understanding the TLS/SSL protocol

I'm currently taking a university class on security and cryptography, and one of the projects we're doing involves implementing a basic TLS socket.

So, I've studied the TLS protocol using both my textbook as well as the latest RFC, so I have a pretty good understanding of how TLS/SSL works, and also how the TLS record format is laid out, byte-by-byte.

So, to start out I decided to write a server program that listens on port 443 and accepts incoming secure HTTP connections. All it does is accept a client connection and then print out a hex dump of the initial message sent by the client.

But when I connect to my server using a web-browser (Firefox), I'm totally baffled by the bytestream the browser sends me. According to the RFC, the first thing a TLS client must do is send a ClientHello message. All messages must be encapsulated in a TLS record format, which is supposed to be formatted like this (using the C-ish notation the RFC uses):

  struct {
      ContentType type;
      ProtocolVersion version;
      uint16 length;
      opaque fragment[TLSPlaintext.length];
  } TLSPlaintext;

The ContentType field is a single enum value that must be one of the following types: change_cipher_spec = 0x14, alert = 0x15, handshake = 0x16, application_data = 0x17

So, since the first thing a client must do is send a ClientHello message, which is part of the handshake, I'd expect the very first byte in the bytestream to be a 0x16, indicating this is a handshake message.

But instead, the actual bytestream my browser sends is:

80 55 01 03 00 00 3c 00 00 00 10 00 00 88 00 00 87 00 00 39 00 00 
38 00 00 84 00 00 35 00 00 45 00 00 44 00 00 33 00 00 32 00 00 96 
00 00 41 00 00 04 00 00 05 00 00 2f 00 00 16 00 00 13 00 fe ff 00 
00 0a 00 00 ff 07 99 58 ad 17 f3 17 23 be 63 8c 6d cb 9b 5f 6f 

I can't make any sense of this bytestream, even after pouring over the RFC for hours. Everything I read about TLS tells me that the first byte should be a 0x16 to indicate a handshake, followed by a two-byte version field, followed by a two-byte record length field. But this byte-stream begins with an 0x80 0x55, which is meaningless to me.

Can anyone clear up what's going on here? Am I misunderstanding some part of the TLS protocol?


What you are seeing is the SSL version 2 compatible hello. Look at appendix E of RFC 5246. I don't believe the newest versions of firefox will send that, they'll only send the V3 hello format that you were expecting.

Need Your Help

strings and characters, how can this python code be translated to swift

python swift

This Python code loops through all characters in a string and prints out characters that belong to a specific subset.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.