一、工作原理
从图中可以看到,实际上https是在tcp层和http层中间插入了一层ssl层,对应到一般的业务架构中,会在前端设置成nginx + tomcat的模式,用nginx来做证书卸载和负载均衡,tomcat做实际的服务;而在实际的抓包过程中,会发现在常规的tcp三次握手之后,还会有ssl的握手过程,在握手之后的实际的业务请求中,也是ssl协议的报文。
那么ssl是怎么做客户端和服务端的连接建立的呢?我们来看下面的一张图:
上图是在tcp连接已经建立好了之后,开始的ssl的连接过程,过程可以分为以下几步:
|
|
以上过程,用表格来表示,即是:
client | server |
---|---|
1. Client Hello | |
2. Server Hello 3. certificate 4. server_key_exchange 5. *certificate_request 6. server_hello_done |
|
7. certificate 8. client_key_exchange 9. certificate_verify 10. change_cypher_spec |
|
11. change_cypher_spec |
下面对连接中的一些细节点做一下解释:
|
|
二、连接过程
我们使用生成的证书,client端ip: 192.168.31.167 server端ip: 192.168.31.176 server端部署nginx,https配置如下:
|
|
这里只分析连接过程
1. tcp建联
可以看到确实首先建立了tcp连接。
2. Client Hello
看一下具体的报文包含了什么:
这里可以看到客户端的session其实还是没有失效的,这时候如果服务端的session也没有失效的话,后续的连接过程是可以减少很多的,这个我们后面的实验再拿出来看。
3. Server Hello
我们可以看到两个信息:
(1) 这时候在server中,这个session是不存在的,这是因为重启nginx导致,实际的session保持是存在的,后面我们实验中继续看;
(2) 使用的是DSA算法;
4. server certificate
这个报文只在使用DSA算法的时候才会使用,我们可以从3中看到现在确实使用的是DSA算法。
5. server key exchange & server hello done
这个报文里承载了两个信息,分别是key exchange和结束标识。
6. client_key_exchange & change_cipher_spec & Hello Request
这里分为三个报文:
(1) client_key_exchange
包含pre-master secret。客户端生成第三个随机数。如果是采用RSA算法,会生成一个48字节随机数,然后用server的公钥加密之后再放入报文中;如果是DH算法,这里发送的就是客户端的DH参数,之后服务器和客户端根据DH算法,各自计算出相同的pre-master secret。
(2) change_cipher_spec
客户端通知服务器开始使用加密方式发送报文。客户端使用上面的3个随机数client random, server random, pre-master secret, 计算出48字节的master secret, 这个就是对称加密算法的密钥。
(3) hello request
客户端发送第一个加密报文。使用HMAC算法计算收到和发送的所有握手消息的摘要,然后通过RFC5246中定义的一个伪函数PRF计算出结果,加密后发送。
7. server new session ticket & change_cipher_spec & 第一个报文
session ticket的用途后续再说。
至此,可以看到所有的连接过程如下:
如果是客户端也需要校验的,还会多出上面表中*给出的过程。