https连接都发生了什么

一、工作原理

这里写图片描述
从图中可以看到,实际上https是在tcp层和http层中间插入了一层ssl层,对应到一般的业务架构中,会在前端设置成nginx + tomcat的模式,用nginx来做证书卸载和负载均衡,tomcat做实际的服务;而在实际的抓包过程中,会发现在常规的tcp三次握手之后,还会有ssl的握手过程,在握手之后的实际的业务请求中,也是ssl协议的报文。
那么ssl是怎么做客户端和服务端的连接建立的呢?我们来看下面的一张图:
这里写图片描述
上图是在tcp连接已经建立好了之后,开始的ssl的连接过程,过程可以分为以下几步:

(1) client hello: 客户端向服务端发出ssl/tls协议的版本号、一个随机数(client random)和客户端支持的ssl加密算法列表;
(2) server hello: 服务端确认双方使用的ssl加密算法,并给出服务端的数字证书和一个随机数(server random);
(3) 客户端确认证书有效,然后生成一个新的随机数(Premaster secret),并使用数字证书中的公钥加密这个随机数,发给服务端;
(4) 服务端使用自己的私钥解析客户端发来的随机数;
(5) 客户端和服务端根据约定的加密算法,使用前面的三个随机数,生成秘钥(session key),用来加密接下来的整个会话过程;

以上过程,用表格来表示,即是:

client server
Client Hello
Server Hello
3. certificate
4. server_key_exchange
5. *certificate_request
6. server_hello_done
*certificate
8. client_key_exchange
9. *certificate_verify
10. change_cypher_spec
change_cypher_spec

下面对连接中的一些细节点做一下解释:

1. ssl/tls握手过程可以分为两种类型:
    * 单向认证: 客户端会认证服务端身份,服务端不会对客户端进行认证;
    * 双向认证: 客户端和服务端互相认证,也就是两者之间会交换证书;
2. 握手过程实际上是通信双发交换协商一个用于对称加密的秘钥的过程,这个过程本身是透明的
3. 在这个过程中会产生单个随机数: Client Random、Server Random、pre-master secret,其中client server random是明文的,而pre-master是加密的(RSA或DH)。
4. 根据3中,加密的算法可以选择RSA和DSA算法,这取决于server端使用什么证书。
   * server使用RSA证书:RSA既可以用作签名也可以用作不对称加密,pre-master secret就是用server的RSA证书中包含的公钥加密的;
   * server使用DSA证书:DSA只能用作签名,所以还需要使用DH算法来交换密钥;
5. 上表中涉及到*的表示在双向认证中才会使用到。

二、连接过程

我们使用生成的证书,client端ip: 192.168.31.167 server端ip: 192.168.31.176 server端部署nginx,https配置如下:

server {
    listen       443 ssl;
    server_name  ssl.alipay.net;

    ssl_certificate      ssl/xxx.net.crt;
    ssl_certificate_key  ssl/xxx.net.key;

    #ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    location / {
        root   html;
        index  index.html index.htm;
    }
}

这里只分析连接过程

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的用途后续再说。
至此,可以看到所有的连接过程如下:

如果是客户端也需要校验的,还会多出上面表中*给出的过程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章