HTTP隧道代理及wireshark抓包分析HTTPS过程

一 序 

为了验证HTTP的隧道代理。我们用抓包分析验证过程


二 使用connect

当客户端向Proxy发起Http CONNECT Method的时候,就是告诉Proxy,先在Proxy和目标服务器之间先建立起连接,在这个连接建立起来之后,目标服务器会返回一个回复给Proxy,Proxy将这个回复转发给客户端,这个Response是Proxy跟目标服务器连接建立的状态回复,而不是请求数据的Response。在此之后,客户端跟目标服务器的所有通信都将使用之前建立起来的建立。这种情况下的Http隧道,Proxy仅仅实现转发,而不会关心转发的数据。这也是为什么在使用Proxy的时候,Https请求必须首先使用Http CONNECT建立隧道。因为Https的数据都是经过加密的,Proxy是无法对Https的数据进行解密的,所以只能使用CONNECT,仅仅对通信数据进行转发。

HTTP隧道代理及wireshark抓包分析HTTPS过程

本图来自《HTTP权威指南》

三 抓包过程(Server端交换证书给client

3.1 HTTP隧道代理及wireshark抓包分析HTTPS过程

HTTP 客户端通过HTTP的CONNECT方法请求隧道代理,创建一条到达任意目的服务器和端口的TCP连接,并对客户端和服务器之间的后继数据进行盲转发。

可以看到,浏览器与代理进行 TCP 握手之后,发起了 CONNECT 请求,报文起始行如下:

[java] view plain copy
  1. CONNECT sp0.baidu.com:443 HTTP/1.1  

对于 CONNECT 请求来说,只是用来让代理创建 TCP 连接,所以只需要提供服务器域名及端口即可,并不需要具体的资源路径。代理收到这样的请求后,需要与服务端建立 TCP 连接,并响应给浏览器这样一个 HTTP 报文:

[html] view plain copy
  1. HTTP/1.1 200 Connection established  

客户端收到了这个响应报文,就可以认为到服务端的 TCP 连接已经打通,后续直接往这个 TCP 连接写协议数据即可。
通过 Wireshark 的 Follow TCP Steam 功能,可以清楚地看到浏览器和代理之间的数据传递:
HTTP隧道代理及wireshark抓包分析HTTPS过程

3.2 HTTPS会话过程

1)客户端发送client hello开始ssl通信,其中包含报文包含客户端支持的一套加密规则(SSL指定版本,加密组件cipher suite)发送给网站。

HTTP隧道代理及wireshark抓包分析HTTPS过程

其中部分关键信息:

ProtocolVersion client_version; //客户端支持的TLS最高版本 
Random random; //客户端生成的随机数,用于之后生成会话** 
SessionID session_id; 
CipherSuite cipher_suites<2..2^16-2>; //支持的加密算法,如RSA 
CompressionMethod compression_methods<1..2^8-1>; //支持的压缩算法 


HTTP隧道代理及wireshark抓包分析HTTPS过程

2服务器可进行SSL通信时,会响应报文server hello ,报文中包含SSL版本及加密组件(加密组件是从接收到客户端加密组件内筛选出来的)。之后服务端将自己的身份信息以证书的形式发回给客户端。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。

HTTP隧道代理及wireshark抓包分析HTTPS过程

部分字段说明:

ProtocolVersion server_version; //确定使用的SSL/TLS版本 
Random random; //服务器端生成的随机数,之后用于生成会话** 
SessionID session_id; 
CipherSuite cipher_suite; //确定使用的加密算法 
CompressionMethod compression_method; //确实使用的压缩算法 

其中选择的加密算法:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)

  • ECDHE : **交换算法,用于生成premaster_secret(用于生成会话**master secret)
  • RSA : 签名算法,用户安全传输premaster_secret
  • AES_128 : 连接建立后的数据加密算法
  • GCM : 一种对称**加密操作的块密码模式

3证书

HTTP隧道代理及wireshark抓包分析HTTPS过程

可以看出百度用的是verisign的证书

4.1 Server Key Exchange Message(可选)

这条消息是用于会话**(premaster secret)生成的,首先这条消息不是必须的,只有在客户端与服务器端双方协商采用的加密算法是DHE_DSS、DHE_RSA、DH_anon时Server Certificate消息中的服务器证书中的信息不足以生成premaster secret时服务器端才需要发送此消息。

4.2 最后服务端发送server hello done通知客户端,表示服务器端已经完成了为支持**交换(生成premaster key)所做的事情,下面开始等待客户端为**交换所要发的消息,最初阶段的SSL握手协商阶段结束。

HTTP隧道代理及wireshark抓包分析HTTPS过程

SSL第一次握手结束

*****************************************************************************

Certificate Request(请求客户端证书,可选)

     如果此次HTTPS连接是双向认证的话,服务器就可以通过此消息请求客户端证书以便进行身份验证。

我们是从百度抓取数据,只需要服务端认证,所以不会发送此消息,这里没有截图。

Client Certificate(客户端证书,可选)

     客户端在收到Server Hello Done与Certificate Request后,表示服务器端需要验证客户端证书,这时客户端需要发送此Client Certificate消息给服务器端,即使没有客户端证书也要发个 certificate_list 列表为空的此消息,服务器端未收到或收到此消息后验证客户端证书,验证结果可酌情处理,如关闭加密通信或忽略此错误等。

********************************************************************************

5.获得服务端证书之后客户端要做以下工作:
a) 验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
b) 如果证书受信任,或者是用户接受了不受信的证书,客户端会生成一串随机数的密码(pre-master secret),并用证书中提供的公钥加密,以报文client-key-exchange。

客户端收到Server Hello Done消息后就发送此消息用于将生成的premaster secret(用于生成会话**master secret)发送到服务器端。根据所采用的非对称加密的算法不同生成premaster secret的方式有所区别。

  • RSA :premaster_secret*是由客户端生成的随机数,用服务器证书中公钥加密后传输,服务器端采用私钥解密。
  • Diffie-Hellman: 对于Diffie-Hellman算法而言,双方通过Server Key Exchange Message 与 Client Key Exchange Message 交换两个数即可各自算出相同的加***,用此当premaster_secret。
HTTP隧道代理及wireshark抓包分析HTTPS过程


生成会话**(master secret)

服务器收到此消息后终于可以生成会话**了,我们要解答几个问题: 
为何要生成master secret?

RSA等非对称加密算法加密大量数据时的性能远小于AES等对称加密算法,所以前面所做的 Key Exchange 操作都是为了生成一个对称加密算法的**,以便提高通信性能。

master secret的生成方法?

使用前面协商的如SHA_256哈希算法由三个随机数client_random、server_random、premaster_secret生成一个安全随机数,采用三个随机数是为了随机性更强

三个随机数都在不可靠网络上传输,如何保证master secret是保密的?

三个随机数中premaster_secret是保密的,所以master_secret也是保密的。


c) 客户端继续发送change cipher Spec报文(
Client发送**改变通知)
用来告诉服务端,此报文之后的通信会采用master secret进行加密。

HTTP隧道代理及wireshark抓包分析HTTPS过程


d)客户端发送finish报文(Encrypted Handshake Message),

报文包含链接至今全部报文的整体校验值。客户端将前面的握手消息生成摘要再用协商好的秘钥加密,这是客户端发出的第一条加密消息。服务端接收后会用秘钥解密,能解出来说明前面协商出来的秘钥是一致的。

HTTP隧道代理及wireshark抓包分析HTTPS过程



6.服务端接收客户端发来的数据之后要做以下的操作:
a) 使用自己的私钥将信息解密取出密码,使用密码解密客户端发来的握手消息,并验证HASH是否与客户端发来的一致。
b) Certificate Verify:如果服务器请求验证客户端,则这消息允许服务器完成验证过程。

7 服务端发送Change cipher spec报文:

服务器端收到 Client Key Exchange Message 通知后即可通知客户端已生成master secret,后面的通信数据用此key加密。

HTTP隧道代理及wireshark抓包分析HTTPS过程

8 服务端发送finish报文(Encrypted Handshake Message)。

服务端也会将握手过程的消息生成摘要再用秘钥加密,这是服务端发出的第一条加密消息。客户端接收后会用秘钥解密,能解出来说明协商的秘钥是一致的。


Application Data

到这里,双方已安全地协商出了同一份秘钥,所有的应用层数据都会用这个秘钥加密后再通过 TCP 进行可靠传输。

HTTP隧道代理及wireshark抓包分析HTTPS过程

总结:


HTTP隧道代理及wireshark抓包分析HTTPS过程
     引用《图解HTTP》总结下HTTPS的流程

后记:

  本文初始目的是为了整理HTTP代理过程,顺带回顾下HTTPS的流程。

举的HTTPS例子也是简单的。单项抓取百度的数据,用抓包工具验证过程。

还有双向验证的,以及高级的优化功能。很底层的加密算法没有去深入展开。

这部分知识在平时的开发过程中很少用到,因为常用都是高级封装好的接口(比如HTTPclient等),但能让我们更清楚地了解 HTTPS 的工作原理,而不仅仅是只知道 HTTPS 会加密数据十分安全。

感谢唐斌斌对于抓包过程的支持。


参考:

https://imququ.com/post/web-proxy.html

http://www.jianshu.com/p/7158568e4867

http://blog.csdn.net/tterminator/article/details/50675540

http://blog.csdn.net/tp7309/article/details/53057429