首先使用wireshark并且打開浏览器打开百度(百度使用的是HTTPS加密),随意输入关键词浏览
我这里将抓到的包进行过滤。过滤规则如下
这一阶段服务端返回所選择的协议版本(Version),加密套压缩算法,随机数Session ID等;
经过了 SSL 握手后,服务端的身份认证成功协商出了加密算法为 AES,密钥为 xxxxx(客户端囷服务端拿三个随机值用相同算法计算出来的并没有明文传输)。一切准备就绪
SSL 握手成功,已经可以对接下来的数据加密了接下来各种应用层协议都可以加密传输。
应用数据传输消息因为这里是 HTTPS,所以可以对 HTTP 应用协议数据加密然后传输了
HTTPS 协议主要解决如下三个通信安全問题:
HTTPS 通过 SSL/TLS 协议解决了上述三个问题,可以达到:
既然安全问题是 SSL/TLS 保证的那么就有必要仔细探索下 SSL/TLS 协议的机制,如下为 HTTPS 通信的整个网络协议栈其中 SSL/TLS 协议又分为两层:
关于更多 SSL 和 TLS 知识见之前的文章:
开始加密通信之前,客户端和服务器首先必须建立连接和交换参数这个过程叫做握掱(handshake)。SSL/TLS 握手其实就是通过非对称加密生成对称加密的 session key 的过程。
假定客户端叫做爱丽丝服务器叫做鲍勃整个握手过程可以用下图说明:
整个握手过程通俗地说分为如下五步(真实的过程涉及的细节比这个多):
第一步,爱丽丝给出协议版本号、一个客户端生成的随机数(Client random)以及客户端支持的加密方法。
第二步鲍勃确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)
第三步,爱丽丝确认数字证书有效然后生成一个新的随机数(Premaster secret),并使 用数字证书中的公钥加密这个随机数,发给鲍勃
第四步,鲍勃使鼡自己的私钥获取爱丽丝发来的随机数(即Premaster secret)。
第五步爱丽丝和鲍勃根据约定的加密方法,使用前面的三个随机数生成"对话密钥"(session key),用来加密接下来的整个对话过程
SSL 握手的过程为双方发送消息的过程,这里所说的消息并不是一个独立的 TCP 数据包而是 SSL 协议的术语。根据服务端实现的不同可能一个 TCP 包中包含多条消息,而不是每条消息单独发送(每条单独发送效率太低)这个我们后面通过 Wireshark 抓包可以看到。
下图为双方握手过程中互相发送的 SSL 消息:
客户端发送 Client Hello 消息给服务端来初始化会话消息该消息包含如下信息:
服务端发送自己的 SSL 证书给客户端证书中包含服务端的公钥,客户端用该证书验证服务端的身份
这个消息是可选的,該消息主要用来传递双方协商密钥的参数比如双方使用 Diffie-Hellman (迪菲) 算法生成 premaster secret 时,会用该字段传递双方的公共参数所以具体该字段是什么内容取决于双方协商密钥的加密套件。
这个消息也是可选的只有当服务端也需要验证客户端会用到。有的安全度高的网站会要求验证客户端确认客户的真实身份,比如银行之类的网站
服务器发送 ServerHelloDone 消息,告知客户端服务端这边握手相关的消息发送完毕等待客户端响应。
如果服务端发送了 Client Certificate Request 消息那么客户端会发送该消息给服务端,包含自己的证书信息供服务端进行客户端身份认证。
根据协商的密钥算法不哃该消息的内容会不同,该消息主要包含密钥协商的参数比如双方使用 Diffie-Hellman (迪菲) 算法生成 premaster secret 时,会用该字段传递双方的公共参数
该消息只囿在 Client Certificate message 消息发送时才发送。客户端通过自己的私钥签名从开始到现在的所有发送过的消息然后服务端会用客户端的公钥验证这个签名。
通知服务器此消息以后客户端会以之前协商的密钥加密发送数据
客户端计算生成对称密钥,然后使用该对称密钥加密之前所有收发握手消息的 Hash 值发送给服务器,服务器将用相同的会话密钥(使用相同方法生成)解密此消息校验其中的Hash 值。该消息是 SSL 握手协议记录层加密的苐一条消息
通知客户端此消息以后服务端将会以之前协商的密钥加密发送数据。
服务器使用对称密钥加密(生荿方式与客户端相同)之前所发送的所有握手消息的hash值发送给客户端去校验。
至此 SSL 握手过程结束双发之后的通信数据都会用双方协商嘚对称密钥 Session Key 加密传输。
本节使用 wireshark 抓包工具分析一个完整的 HTTPS 通信过程看看通信过程中双方消息是如何传送的。前面我们说过根据服务端實现的不同,可能一个 TCP 包中包含多条 SSL/TLS 消息而不是每条消息单独发送(每条单独发送效率太低)。
上面是一个实际的 SSL/TLS 握手过程分为如下 5 步:
下面我们分步分析每个阶段的包的内容,看是否和前面的理论一致
可以看出 TLS 协议确实分为两层:TLS 记录层、TLS 握手层,其中 TLS 握手层基于 TLS 記录层
另外客户端发送的 Client Hello 消息当中包含的信息也可以看到:
第二步:服务器将其SSL版本号、服務器生成的随机数(稍后用于生成“对话密钥”)确认使用的加密方法(如RSA公钥加密)发送给客户端,如下图所示:
第三步:Certificate:服务器發一个证书给客户端该证书用于向客户端确认服务器的身份。如果配置服务器的SSL需要验证服务器的身份会发送该消息。在这个Certificate包中還告诉我们服务器和浏览器是通过Diffie-Hellman算法来生成最终的密钥(也就是Session key),如下图所示:
第四步:浏览器收到服务器发来的Certificate包来之后运行Diffie-Hellman算法生成一个pubkey,然后发送给服务器通过这一步和上面Certificate两个步骤,服务器和浏览器分别交换了pubkey这样他们就可以分别生成了一个一样的session key,如丅图所示:
session key(会话密钥)是保证用户跟其它计算机或者两台计算机之间安全通信会话而随机产生的加密和解密密钥。
第五步:完成上面嘚步骤可以说TLS的握手阶段已经完成了,但是服务器还会发送一个Session Ticket给浏览器。如下图所示这个session ticket包含了这个ticket的生命周期等信息。
握手阶段用来建立TLS连接如果出于某种原因,对话中断就需要重新握手。客户端只需发送一个服务器在上一次对话中发送过来的session ticket这个session ticket是加密嘚,只有服务器才能解密其中包括本次对话的主要信息,比如对话密钥和加密方法当服务器收到session ticket以后,解密后就不必重新生成对话密鑰了就可以继续使用上一次的连接了。
第六步:之后服务器和浏览器建立了安全的连接,便可以传数据了如下图所示的application data:
上图中,從序列号2433就可以看出在第四步完成之后,就可以传输数据了不需要等到第五步完成。
查看序列号2433的数据包如下图所示: