一文读懂HTTPS

1,390 阅读8分钟

前言

关于HTTPS的文章有很多,大家的文章讲的那是真的详细,功底我着实佩服。虽然已经有了这样优秀的文章,但不影响我写作的热情,学习知识,分享是必不可少的一环。文章不是照搬,而是自己理解加工后纯手打的

学习前端开发果然还是绕不开计算机网络基础,今天面试挂在了这里,痛定思痛,让我们一起来了解下HTTPS到底是个什么玩意。

灵魂拷问

你是否曾认为,证书是用来加密的?😄

对称加密

通信双方,使用同一个密钥对信息加密和解密。只有知道密钥的人才能获取内容。

但通信双方必须约定好密钥,且不能泄露密钥。而实际上,只要使用网络传输,就存在报文泄露的风险。何况HTTP协议本就是明文传输,双方约定密钥的过程,完全是众目睽睽之下。这种情况下无法保证你的密钥没有被第三方截获。隔墙有耳一说,对吧?所以出现了非堆成加密

非对称加密

通信双方每个人都有两把钥匙,公钥任何人都可以知道,私钥只有自己知道

且存在这样一个特点:使用公钥加密的内容,只有对应的私钥才能解开,使用私钥加密的内容,只有对应的公钥才可以解开。所谓,非对称。

根据这样的特点,A发消息给B,使用B的公钥加密,B收到后使用自己的私钥解密,就可以获取到内容了。

所以通信时,双方首先要互换公钥。A和B通信开始后,中间人完全可以在截获A的公钥后,替换成自己的公钥发送给B,只要B使用该公钥加密,中间人就可以使用自己的私钥解密,获得内容。双方的通信虽不至于众目睽睽,却也暴露给了中间人,总归是不安全的。

你可能要问了,那B不用中间人的公钥加密不就好了?

实际上B并不知道该公钥是不是A的,A也同样不确定它收到的公钥是不是来自B。

所以引出了一个问题。A如何判断你加密使用的公钥确实是B的,而不是中间人的?即,如何判断公钥身份是否有效

数字证书:

联系实际,考虑到身份证明必须要第三方机构,我们必须无条件信任它。自己是没办法证明自己的身份的。这个第三方机构一般是CA(Certificate Authority),颁发证书的具体过程如下:

B将自己的个人信息,和公钥发送给CA机构(这里会不会出现中间人攻击?),CA机构使用哈希算法对发来的个人信息和公钥进行计算,生成一个摘要,并使用CA自己的私钥进行加密生成数字签名。最后将数字签名和原信息(B的公钥和信息)合并,生成数字证书。

这里用到了哈希算法,它的特点是,只要原信息变化,计算得到的值就会发生巨大的变化。以此来确认内容是否遭到篡改

再借鉴一张图:

生成证书的过程

所以,在通信时,B先将自己的证书发送给A,A使用同样的哈希算法,对证书内B的信息进行计算,生成一份摘要。同时对证书内的数字签名进行解密,拿到事先加密的摘要,对比两份摘要的内容是否一致,便可以确定公钥是否被篡改。

最根本的问题

  1. 公钥发送给CA机构的过程中,不会被中间人拦截吗?
  2. 数字签名是使用CA的私钥加密的,解密需要使用CA的公钥,我们如何获取?获取公钥的过程中如果又被截获了,岂不成了死循环?

根证书

以下内容摘自百度百科

根证书是CA认证中心给自己颁发的证书,是信任链的起始点。安装根证书意味着对这个CA认证中心的信任。从技术上讲,证书其实包含三部分,用户的信息,用户的公钥,还有CA中心对该证书里面的信息的签名。验证一份证书的真伪(即验证CA中心对该证书信息的签名是否有效),需要用CA 中心的公钥验证,而CA中心的公钥存在于对这份证书进行签名的证书内,故需要下载该证书,但使用该证书验证又需先验证该证书本身的真伪,故又要用签发该证书的证书来验证,这样一来就构成一条证书链的关系,这条证书链在哪里终结呢?答案就是根证书,根证书是一份特殊的证书,它的签发者是它本身,下载根证书就表明您对该根证书以下所签发的证书都表示信任,而技术上则是建立起一个验证证书信息的链条,证书的验证追溯至根证书即为结束。所以说用户在使用自己的数字证书之前必须先下载根证书。

一般来说,根证书是内置在操作系统/浏览器中的,随操作系统的发布而发布。你信任操作系统,也就信任了这份证书。这就是证书链条的终点。

HTTPS

终于到了HTTPS。前面我们提到了加密算法和证书。HTTPS是如何选择的?

首先,安全起见,我们应该使用非对称加密算法。但实际上这种算法的效率并不够高,可以想象,存在两次加密解密的过程。而对称加密算法的效率就还算不错。于是产生了这样一种思路:

使用对称加密算法来传输信息,但密钥使用非对称加密算法来传输。所以希望大家牢记:HTTPS中,非对称加密算法,仅用来传递对称加密算法的密钥

握手过程

HTTPS握手过程分为四个阶段:

  1. 浏览器发起HTTPS请求,生一次个随机数,附带上支持的加密算法列表和协议版本号。
  2. 服务器验证协议版本号是否一致,一致则生成一个随机数,随证书一同发送回客户端,否则拒绝请求。
  3. 浏览器通过根证书验证服务器证书是否有效,若有效则说明证书中的服务器公钥有效。生成一个随机数,再生成一个所有内容的哈希值(一共三个随机数),并使用服务器公钥加密后发送。若证书无效,则浏览器提示风险。
  4. 服务器接收到之后,使用私钥解密发来的内容,并对所有内容进行同样的哈希值计算,再和收到的哈希值比对。若内容一致,则通过三个随机数按照约定的加密算法生成会话密钥(也就是对称加密密钥),并回应客户端握手完成。

注意到,前两次握手过程是明文传输的。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用会话密钥来加密内容

为什么需要三个随机数?这三个随机数又被称为pre-master key

引用d520的解释

不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。 对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。 pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。

断开连接后如何恢复:

  1. session ID:每一次会话都有一个编号,会话中断后再次连接需要客户端给出这个编号。服务器有这个记录则不用重新连接。此种方式对分布式集群不太友好
  2. session ticket:只有服务器能解密,里面包含会话信息。是在上一次会话中发给用户的。

参考

  1. 【阮一峰】SSL/TLS协议运行机制的概述
  2. 【码农翻身公众号】一个故事讲完HTTPS