SSL 隧道建立过程

Posted by pggsnap on July 5, 2018

通过 netty 实现 https 请求转发

  1. 代理应用监听端口 7101,如果是 http 请求,解析出 ip 地址和端口后直接转发即可。

  2. 如果是 https 请求,客户端首先会明文发送一条 CONNECT 请求,可以根据该请求解析出 ip 和 port;之后代理应用与目标服务器建立 tcp 连接后,通知客户端连接已建立。之后客户端开始发起 SSL 握手,握手成功后即可以发送加密数据。代理应用作为客户端和服务器之间的桥梁,不作任何处理,直接转发请求和应答即可。

流程

  • No.5-7 客户端发送 https 请求前,与代理应用进行 tcp 三次握手,连接建立。客户端 127.0.0.1:49344 <-> 127.0.0.1:7101 代理应用。

  • No.9 客户端发送 CONNECT 请求,目的服务器是 localhost:8443。

  • No.11-13 代理应用与目标服务器进行 tcp 三次握手,建立连接。代理应用 127.0.0.1:49345 <-> 127.0.0.1:8443 目标服务器。

  • No.15 代理应用返回 200 给客户端,说明与目标服务器连接已建立。

  • No.17 客户端发送 Client Hello 请求,准备建立 ssl 连接。内容包括协议版本,随机数 Random1,可选加密类型等。

  • No.19 代理应用转发 Client Hello 请求给目标服务器。

  • No.21 目标服务器响应,内容包括:

Server Hello:选定加密套件,决定了后续加密和生成摘要使用的算法;生成随机数 Random2。

Certificate:下发证书,客户端可以通过证书获取公钥。

Server Key Exchange:如果是DH算法,这里发送服务器使用的DH参数。RSA算法不需要这一步。

Certificate Request:服务器要求客户端上报证书,这一步是可选的,对于安全性要求高的场景会用到。

Server Hello Done:通知客户端 Server Hello 过程结束。

  • No.25 代理应用将 Server Hello 等响应转发给客户端。

  • No.27 客户端发送 Certificate 等多个请求。具体包括:

Certificate:获取证书、验证合法性后取出公钥,客户端生成随机数 Random3,在用公钥加密后生成 PreMaster Key(这一步是确保整个 https 数据安全的关键:https 后续数据传输是基于对称加密算法的,而对称加密的秘钥由随机数 Random1+Random2+Random3,经过算法加密后得到;而整个 SSL/TLS 握手阶段数据都是明文传输的,这也就意味着代理应用可以直接获得 Random1、Random2 的值,以及 PreMaster Key。PreMaster Key 是被公钥加密过的,只有拥有私钥的服务器才能够解密后得到随机数 Random3,代理应用无法解密)。

Client Key Exchange:客户端发送 PreMaster Key。

Change Cipher Spec:通知后面发送的消息都会使用协商出来的秘钥加密了。

Encrypted Handshake Message:将前面的握手消息生成摘要,再用协商好的秘钥加密后发送出去。

  • No.29 客户端发送加密数据。

  • No.31 代理应用将收到的 Certificate,Client Key Exchange 等多个请求以及 Application Data 都转发给服务器。

  • No.33, 35:Change Cipher Spec:服务通知后面的消息会用协商出来的秘钥加密;Encrypted Handshake Message:服务器将前面的握手消息生成摘要,再用协商好的秘钥加密后发送出去,如果客户端能够解密,说明秘钥是一致的。

  • No.37:代理应用转发响应给客户端。

  • No.39:服务器把响应发送给代理应用。

  • No.41:代理应用转发响应给客户端。

参考

SSL/TLS 握手过程详解