TLSSSL协议详解(9)Clienthello
SSL报⽂格式可以⼤致分为2部分,Record层和 Handshake层,Record层中指定了后续数据的类型,SSL版本(⼀般来说固定),以及后续数据的长度。Handshake层欧威Record层的负载,其关系类似TCP层的数据作为IP层的负载。
例如上图中显⽰的那样,SSL报⽂头部是TVL格式:
Content Type: Handshake
Version: TLS 1.0
Length: 121
这些表⽰后续的Handshake层是握⼿报⽂,TLS1.0格式,总长度是121字节。
⽽Handshake层,⼜有⾃⼰的格式,根据不同的类型,⽐如Client Hello,Certificate,等,有⾃⼰的格式(所以Record中
的Content Type字段是必要的),并且不同的版本之间也有不同的格式,例如TLS1.0和SSL 3.0对Client key exchange报⽂有⾃⼰的组织⽅式(所以Record中的Version字段也是必要的)。长度字段有效的确定了单个SSL报⽂结束的位置,因
为SSL报⽂承载与TCP之上,⼀个TCP段中存在多个SSL报⽂是⾮常常见的事情,如果没有字段描述单个SSL报⽂的长度,那么解析报⽂将变得不可能。
(1)Random
随机数,⼀共32字节,其中前4个字节使⽤系统当前时间,后28字节使⽤伪随机函数⽣成的随机数。4个字节以Unix时间格式记录了客户端的协调世界时间(UTC)。协调世界时间是从1970年1⽉1⽇开始到当前时刻所经历的秒数,那么时间是不断的上涨的,通过前4字节填写时间⽅式,有效的避免了周期性的出现⼀样的随机数。使得“随机”更加“随机”。随机数⽤来⼲什么?随机数是⽤来⽣成对称密钥的,我们后续讲到⽣成对称密钥的时候,会再次提到随机数。现在只需要记住“客户端⽣成了⼀个随机数,然后发送到的服务器”。
然⽽在具体的实现上,不同客户端⾏为不⼀样,IE会带时间,⽽Firefox就不带时间,因为它本⾝的含义就是随机数,⽽对端也不会校验这个时间(和tcp的时间戳完全不是⼀回事⼉)。
随机数参与了SSL握⼿的 master key的计算、KDF计算、server_key_exchange的签名值的计算。属于混淆的⼀部分。
(2)Session id
标识了后⾯Session id的长度,但是对于⼀般新建的会话,Session id length都是0,如果Session id length有值,对于SSL 2.0 Session id length0~16字节,其后的版本扩⼤到32字节。本报⽂中Session id length是0,后⾯就没有跟Session id,直接是Cipher suit length。下⾯是Session id不是0的报⽂:
⼀眼就能看出差别了把!Session id在会话复⽤中被⽤到,我们讲到会话复⽤的时候,会提及Session id,本章分析报⽂时,不会再提及Session id。
Session id并不⼀定是32字节,RFC规定可以0~32字节。只是Session id由服务器⽣成,服务器普遍采⽤OpenSSL,
⽽OpenSSL基本只⽣成32字节的session id,如果碰到其他字节长度的Session id,切莫认为是异常client hello。
(3)Cipher Suite
Cipher Suits Length:含义同Session id length
Cipher Suits:加密套件,它列出了客户端能够⽀持的加密⽅式、算法等信息。不同的加密套件性能不⼀样,安全性不⼀样,也导致了SSL交互报⽂的不⼀样。
最常见的如TLS_RSA_WITH_RC4_128_SHA1,它表⽰我们密钥交换使⽤RSA,⾝份认证算法⽤RSA(咦,怎么和之前说的不⼀样,⾝份认证难道不是证书吗?是的,证书是⾝份认证⼀部分,我们还需要⽤RSA去验证证书,后⾯会讲到),对称加密算法使⽤RC4,摘要算法使⽤SHA1。再举个例⼦,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA1,它表⽰,密钥交换算法使⽤ECDHE(短暂椭圆
曲线),⾝份认证算法使⽤ECDSA,对称加密算法使⽤AES_128_CBC,摘要算法使
⽤SHA1。
客户端把⾃⼰所⽀持的加密套件全部发送给服务器,服务器会从中选择⼀个加密套件。这个我们将在后⾯的Server
hello中讲到。
每个加密套件⽤2字节表⽰,这⾥⼀共12个加密套件,所以理所当然的,Cipher Suits Length是12 * 2 = 24字节。
(4)Compression Methods
⽬前没见过使⽤压缩算法的实例。这⾥不再拓展。
(5)Extension
拓展字段的存在,是因为SSL协议起草之初有些功能没有考虑到,后续这些功能被加进RFC,⽽为了兼
容SSL,把这些功能的描述放到Extension中。Extension很⼤程度上影响了SSL的流程,很多⼈觉得某些SSL连接的报⽂好奇怪、和正常接触
的SSL报⽂不⼀样,就是因为Extension起的作⽤。
TLS 1.3 就借助 extension 发送不同curve的pubkey来减少RTT,后续有机会再说。这⾥介绍主流的⼀些拓展。
(1)Renegotiation info:
如果是重新协商(即加密的hello),那么会带上上次协商的12字节的finished,如果是新hello请求,那么⾥⾯字段为0。
切记及时服务器端不⽀持renegotiation,在server hello响应时也需要带上这个拓展(前提是客户端有这个拓展或者有等价的EMPTY_SCSV,因为我在实现上碰到过如果不带该拓展,导致客户端结束连接的情况)。
(2)Server_name(SNI):
SSL存在验证证书的时候,有这么⼀个判断:⽐较“浏览器输⼊的地址”和“获取的证书的名称”,如果⼀样,那么接着验证,如果不⼀样,那么认为证书是不可信的。
假设有公司的域名存在2个:和,它们对应的ip都是222.12.34.56,假设服务证书的名字是 ”www.123”  ,那么从”www.567” 访问过来的⽤户⽆法信任服务器证书,总之,总有⼀个域名访问会导致客户端⽆法信任服务器。为了解决这个问题,客户端在client hello中带上server name 拓展(如果使⽤ip地址进⾏访问,那么就不会有server name拓展),它会捎带上域名地址,服务器解析到server name后,就会根据server name中的域名,选择合适的证书。
(3)Elliptic_curves/ec_point_formats:
使⽤椭圆曲线密钥交换算法的时候⽤到,⾥⾯列举了⾃⼰⽀持的椭圆曲线算法,供服务器选择。
(4)application_layer_negotiation(ALPN):
⽤以描述⽀持的上层协议,h2、http/1.1、spdy等。可以把他想象成IP头中的protocol,描述了上层是TCP还是UDP还
是ICMP。
⽬前主流浏览器,若要使⽤HTTP2,则必须使⽤这个拓展。
(5)status_request
请求OCSP,服务器可以发送cettificate status到客户端,⾥⾯带上ocsp的信息。
(6)signature_algorithms
表⽰⾃⼰⽀持的签名算法,服务器收到这个拓展,在进⾏例如server key exchange签名等操作时,需要参考客户端这个拓展。
(7)SessionTicket TLS
ssl协议是指什么
Session ticket会话复⽤时使⽤,讲到session ticket时再说。
注意,⽼的⼀些客户端没有extensions length字段,⽽新的客户端如果不携带extension,他也会有extensions length,只是为0。所以判断有没有extension 存在的⽅式是compression methods是否在client hello的最后。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。