HTTPS & TLS/SSL
大约 3 分钟
HTTPS & TLS/SSL
https 其实就是在 http 这个应用层协议上加了一层 TLS/SSL 的校验。
http 本身是无状态的,因此它并不安全,同时它基于 tcp/ip,数据都是明文传输,存在安全隐患。因此我们使用了 TLS/SSL 对其报文进行了加解密。
TLS 和 SSL 本质上是一个东西,前者是最初的名字,TLS 是后来基于 SSL 更新的版本。
https 会在 tcpip 三次握手后尝试建立连接,我们来聊一下 TLS/SSL 是怎么建立连接的:
在建立连接前,TLS/SSL 用的是非对称加密,即公钥和私钥都可以用于加密与解密。因此非对称加密的性能消耗会比较大。
以前是服务器下发公钥给到客户端,客户端使用公钥加密内容传输到服务器,服务器再使用私钥进行解密。但是这个过程存在安全隐患,如果有人能模仿出公钥,那它也可以通过这个方式与服务器进行交互了。因此引申出了 CA 这个安全机构。
现在建立连接的前置过程是:
- 提交公钥给到 CA,CA 将公钥打包成安全证书,这个证书包含公钥信息但并不是公钥,证书需要借助 CA 的公钥才可以得到服务器的公钥信息
- 服务器下发证书给到客户端,客户端拿 CA 公钥解出服务器的公钥信息,然后使用解出来的公钥加密内容传输到服务器
- 服务器使用私钥解密
CA 的公钥会预先存放在浏览器和操作系统中,因此 CA 是十分可信的机构。要有新的机构我们需要更新浏览器或者操作系统?
上面关注的重点是如何借助 CA 实现对公钥的保护,下面总结一下建立 TLS/SSL 连接的前置过程:
- 客户端向服务端发起 clientHello 请求,带上一个 client 随机数、TLS 版本号、密码套件(即加密方式)列表(第一次通信)
- 服务端接收到 clientHello 请求,获取到 client 随机数、TLS 版本号、密码套件列表,同时判断版本号是否匹配,套件是否支持;都满足条件的话,服务端发送 serverHello 请求,带上一个 server 随机数、使用的 TLS 版本号、使用的密码套件,同时服务器下发证书给到客户端(第二次通信)
- 客户端接收到 serverHello 请求,此时拥有 client 随机数、server 随机数、证书。客户端拿 CA 公钥解出服务器的公钥信息,同时客户端生成一个 pre-master 随机数,通过算法将 client 随机数、server 随机数、pre-master 随机数这三者计算出一个会话密钥,将会话密钥存储下来,然后使用证书解出来的公钥将会话密钥进行加密,向服务器发起请求,带上加密后的会话密钥,同时告诉服务器后续我们就使用这个会话密钥进行通信(第三次通信)
- 服务器接收到请求,通过服务器端的私钥将加密的会话密钥解密出来,得到会话密钥并存储下来,同时向客户端发送确认请求,告知客户端后续我们就用这个会话密钥进行通信(第四次通信)
在这四次通信之后,TLS/SSL 建立连接成功,后续就是对称加密,即加解密使用同一个密钥,即上面说到的会话密钥。每次通信报文都使用会话密钥进行加解密,对称加密的性能消耗比非对称加密小很多。
需要注意的是,上面都是基于 RSA 算法的密钥交换算法,以前用的比较多。现在基本用的都是 ECDHE 算法。