了解TLS/SSL协议

Cha*_*l72 5 security encryption ssl network-protocols

我目前正在攻读安全和加密大学课程,我们正在做的其中一个项目涉及实现一个基本的TLS套接字.

所以,我已经使用我的教科书和最新的RFC研究了TLS协议,所以我对TLS/SSL的工作方式有了很好的理解,并且对TLS记录格式的布局也是如此,逐字节.

因此,首先,我决定编写一个侦听端口443并接受传入安全HTTP连接的服务器程序.它只是接受客户端连接,然后打印出客户端发送的初始消息的十六进制转储.

但是当我使用网络浏览器(Firefox)连接到我的服务器时,我完全被浏览器发送给我的字节流所困惑. 根据RFC,TLS客户端必须做的第一件事就是发送ClientHello消息.所有消息必须封装在TLS记录格式中,该格式应该是这样格式化的(使用RFC使用的C-ish表示法):

  struct {
      ContentType type;
      ProtocolVersion version;
      uint16 length;
      opaque fragment[TLSPlaintext.length];
  } TLSPlaintext;
Run Code Online (Sandbox Code Playgroud)

ContentType字段是单个枚举值,必须是以下类型之一:change_cipher_spec = 0x14, alert = 0x15, handshake = 0x16, application_data = 0x17

因此,由于客户端必须做的第一件事就是发送ClientHello消息,这是握手的一部分,我希望字节流中的第一个字节是a 0x16,表明这是一个握手消息.

但相反,我的浏览器发送的实际字节流是:

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 
Run Code Online (Sandbox Code Playgroud)

即使经过RFC几个小时之后,我也无法理解这个字节流.我读到的关于TLS的所有内容都告诉我,第一个字节应该是a 0x16表示握手,后跟一个双字节版本字段,后跟一个双字节记录长度字段.但是这个字节流以a开头0x80 0x55,这对我来说毫无意义.

任何人都可以清理这里发生了什么吗?我误解了TLS协议的某些部分吗?

Jam*_*olk 9

你看到的是SSL版本2兼容你好.看RFC 5246附录E.我不相信最新版本的firefox会发送它,它们只会发送你期望的V3 hello格式.


roo*_*ook 5

Wireshark有一个HTTPS/TLS/SSL解析器,这将能够理解握手的纯文本部分.

还要确保阅读HTTPS连接的前几毫秒.