TLS-wireshark-抓包记录

本文最后更新于:2021年5月4日 中午

基本信息

分层

SSL报文格式可以大致分为2部分:Record层 和 Handshake层

Record层:指定了后续数据的类型,SSL版本(一般来说固定),以及后续数据的长度 Handshake层:Record层的负载,其关系类似TCP层的数据作为IP层的负载

SSL报文头部是 Content Type, Version, Length (TVL)格式

表示后续的 Handshake层 是握手报文,TLS1.0 格式,总长度是512字节

  • Content Type
    Handshake层,根据不同的类型 (Client Hello,Certificate 等),有自己的格式. 所以Record中的Content Type字段是必要的

  • Length
    长度字段有效的确定了单个SSL报文结束的位置
    因为SSL报文承载与TCP之上,一个TCP段中存在多个SSL报文是非常常见的事情,如果没有字段描述单个SSL报文的长度,那么解析报文将变得不可能

  • Version
    不同的版本的协议之间也有不同的格式,所以Record中的Version字段也是必要的

Handshake

Client Hello

Random


随机数,一共32字节,其中前4个字节使用系统当前时间,后28字节使用伪随机函数生成的随机数。4个字节以Unix时间格式记录了客户端的协调世界时间(UTC)。协调世界时间是从1970年1月1日开始到当前时刻所经历的秒数,那么时间是不断的上涨的,通过前4字节填写时间方式,有效的避免了周期性的出现一样的随机数。使得“随机”更加“随机”

作用:随机数是用来生成对称密钥的,生成对称密钥的时候,会再次提到随机数。现在只需要记住 “客户端生成了一个随机数,然后发送到的服务器”

然而在具体的实现上,不同客户端行为不一样,IE会带时间,而 Firefox 就不带时间,因为它本身的含义就是随机数,而对端也不会校验这个时间

随机数参与了SSL握手的 master key的计算、KDF计算、server_key_exchange的签名值的计算。属于混淆的一部分

Session ID Length 与 Session ID


Session ID Length 标识了后面 Session ID的长度
但是对于一般新建的会话,Session ID 与 Session ID Length 都是0
对于 SSL 2.0来说 Session ID Length 为 0~16字节,其后的版本扩大到32字节

Session ID并不一定是32字节,RFC规定可以0~32字节。只是Session id由服务器生成,服务器普遍采用OpenSSL,而OpenSSL基本只生成32字节的Session ID
如果碰到其他字节长度的Session ID,切莫认为是异常 Client Hello

Cipher Suite Length 与 Cipher Suite


Cipher Suits Length 记录着 Cipher Suite 长度。每个加密套件用2字节表示,这里一共12个加密套件,所以理所当然的,Cipher Suits Length= 43 * 2 = 86字节

Cipher Suits:加密套件,它列出了客户端能够支持的加密方式、算法等信息。不同的加密套件性能不一样,安全性不一样,也导致了SSL交互报文的不一样

加密算法名称一般会按照 密钥交换时(身份验证时)__对称加密时_摘要时 命名
TLS_RSA_WITH_RC4_128_SHA1,表示密钥交换使用RSA,身份认证算法用RSA(用RSA去验证证书),对称加密算法使用RC4,摘要算法使用SHA1
客户端把自己所支持的加密套件全部发送给服务器,服务器会从中选择一个加密套件

Compression Methods


记录着压缩算法。这里并未使用

Extension


拓展字段的存在,是因为SSL协议起草之初有些功能没有考虑到,后续这些功能被加进RFC,而为了兼容SSL,把这些功能的描述放到Extension中
Extension很大程度上影响了SSL的流程,很多人觉得某些SSL连接的报文好奇怪、和正常接触的SSL报文不一样,就是因为 Extension 起的作用

一些常见的 Extension

  • Extension: server_name(SNI)
    客户端提供连接中要访问的virtual hostname

    SSL存在验证证书的时候,有这么一个判断:比较“浏览器输入的地址”和“获取的证书的名称”,如果一样,那么接着验证,如果不一样,那么认为证书是不可信的

    假设有公司的域名存在2个:www.123.comwww.567.com, 对应的ip都是222.12.34.56
    如果服务证书的名字是www.123.com,那么从www.567.com访问过来的用户就不会信任服务器的证书。总有一个域名访问会导致客户端无法信任服务器
    为了解决这个问题,客户端在client hello中带上 Extension: server name(如果使用ip地址进行访问,那么就不会有此拓展),它会捎带上域名地址,服务器解析到server name后,就会根据server name中的域名,选择合适的证书

  • Extension: renegotiation_info
    允许客户端或服务器启动重新协商-新的加密方式

    如果是重新协商(即加密的hello),那么会带上上次协商的12字节的finished,如果是新hello请求,那么里面字段为0。
      切记, 即使服务器端不支持,在server hello响应时也需要带上这个拓展(前提是客户端有这个拓展或者有等价的EMPTY_SCSV。因为如果不带该拓展,可能会导致客户端结束连接)
  • Extension: ec_point_formats / Elliptic_curves

    使用椭圆曲线密钥交换算法的时候用到,里面列举了自己支持的椭圆曲线算法,供服务器选择
  • Extension: application_layer_protocol_negotiation(ALPN)
    用以描述支持的上层协议,h2、http/1.1、spdy等

    可以把他想象成IP头中的protocol,描述了上层是TCP还是UDP还是ICMP
    若要使用 HTTP2,则必须使用这个拓展
  • Extension: status_request
    请求OCSP,服务器可以发送 cettificate status 到客户端,里面带上ocsp的信息

    OCSP wiki
    由数字证书认证机构运行的OCSP服务器会对请求返回经过其签名的证书状态信息,分别为:正常(Good)、已废除(Revoked)、未知(Unknown)。如果有无法处理的请求,则会返回一个错误码

  • Extension: signature_algorithms
    表示自己支持的签名算法

    服务器收到这个拓展,在进行例如server key exchange签名等操作时,需要参考客户端这个拓展
  • Extension: session_ticket

    Session ticket会话复用时使用

所有可使用 Extension 可以查询 iana.org的Extension记录
此网站记录了所有的 Extension 规范

Hello Retry Request