HTTPS 是被广泛应用在网络中的一种加密通信协议,也被叫做在 TLS 之上的 HTTP。TLS 以及前身 SSL 是传输层安全协议,给网络通信提供安全和数据完整性的保障,所以它能很好的解决 HTTP 的数据明文和劫持篡改的问题。并且其分为记录层和传输层,记录层用来确定传输层数据的封装格式,传输层则用于数据传输,而在传输之前,通信双方如何彼此信任和建立一个安全通信方式,是需要我们深入了解的。

目前推荐的 TLS 版本是 1.2,协议具体内容可以在 The Transport Layer Security (TLS) Protocol Version 1.2 中去仔细了解,它是08年8月发表的。 TLS 1.3 到16年1月都还只是草案。

准备

这里我使用 Wireshark 来抓包看 HTTPS 的握手过程,首先我们需要开启网卡

1
sudo chmod 777 /dev/bpf*

否则会提示:

1
no interface can be used for capturing in this system with the current configuration

开启之后,我们在浏览器内访问一个 https://xxx 的网站,再过滤出 ssl,不难找到我们所需要的信息。

正文

我截取了其中一段

握手总结起来就是双方身份验证,协商加密算法,交换加密密钥。

而这些步骤有些服务器是合并在一起发送,例如:

Client Hello

首先客户端会发送一个 Hello 消息给服务端:

Version: TLS 1.2 是其版本信息,Random 是由客户端生成的随机数,长度为28个字节(用于协商密钥),Cipher Suites 是客户端支持的加密算法,让服务端从中选择一个,Compression Methods 是压缩方法,以及一些额外的信息。

Server Hello

服务端在收到客户端发起的 Hello 之后,同样回给客户端一个 Hello:

里面包含了协商后的版本信息 TLS 1.2,使用的加密算法 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 和压缩方法,以及服务端生成的随机数(用于协商密钥)。

Certificate

同时服务端也会配置并返回对应的证书,用来身份验证和密钥交换。

证书生成

申请者需要向颁发证书的可信第三方CA机构提交域名、公钥和请求文件(.cer文件),CA机构验证信息的合法真实性后颁发证书,里面分为明文信息和签名信息,明文信息包括域名,申请者信息和颁发机构,有效期,公钥等信息,签名信息是通过CA私钥对明文信息进行加密后的内容,申请者在安装证书后,可以通过证书公钥来对签名信息和明文信息进行验证。

证书验证

验证分为两部分,验证证书本身的合法性和验证颁发者的合法性。

我们知道证书是分层级的,下一级的证书需要用上一级证书的私钥签名,所以需要通过使用上一级证书的公钥来解密得到下一级的签名摘要,同时客户端也如此操作,最后对摘要进行对比验证。

颁发者合法性则是检查浏览器和操作系统中的可信证书列表。所以有时候不要乱安装一些奇奇怪怪的证书。

Server Key Exchange, Server Hello Done

Server Key Exchange 用来加密下一步中的 Client Key Exchange ,只有当证书中不包含公钥的时候才需要,比如用 Diffie Hellman 密钥交换算法。

Server Hello Done 表示服务端 Hello 的结束。

Client Key Exchange

此时客户端在验证证书通过之后,客户端需要再传递一个随机数给客户端,这里涉及到两种方式,一种是通过 RSA 加密,客户端先生成48字节的随机数,再用证书的公钥加密,然后发给服务端,另一种是这里客户端用的是 Diffie-Hellman 密钥交换算法,所以这条消息会包含客户端的 Diffie-Hellman 公钥。

Encrypted Handshake Message, Application Data

此时双方根据客户端生成的2个随机数和服务端生成的1个随机数,使用相同的算法得到一个协商密钥,对数据进行对称加密得到 Encrypted Application Data,然后再进行通信,对方再进行解密,从而保证数据传输的安全性。

总结

HTTPS 请求过程主要分为握手和数据传输两步,握手是在双方验证身份之后,协商出一个密钥,数据传输则是使用之前协商的密钥,对数据进行加密传输。

本文是对 HTTPS 请求的一个简单的理解笔记,欢迎大家一起学习交流~