HTTPS协议详解

HTTPS

什么是 HTTPS ?一句话:HTTPS = HTTP + SSL

HTTPS 并不是一个全新的协议,而是在 HTTP 的基础上,通过 SSL 增加了一层加密协议,从而大大增加了 HTTP 协议的安全性。

为什么需要 HTTPS

上面简单讲了一下 HTTP。在正式讲 HTTPS 之前,首先我们要搞清楚 HTTP 的缺点是什么,为什么需要 HTTPS。

我们知道,HTTP (除了最新的 HTTP/3 外),传输层是基于 TCP 协议的。TCP 建立连接时,有三次握手。三次握手完毕之后,TCP 连接就顺利建立了,接下来两端将会传输数据。

对于普通的 HTTP 协议,在建立完 TCP 连接之后,就直接开始传输数据了,这时候数据是明文传输的,这也是 HTTP 最不安全的地方。

明文传输是什么概念呢?我们知道,浏览器和服务器之间,是存在很长一条路线的,你在家里通过浏览器访问网页的时候,数据会从你的电脑,传到你家里的路由器,再到光猫,到运营商,到互联网…直到最后才到服务器。在明文传输下,理论上来讲,浏览器和服务器之间的任一节点,包括你家里的路由器、包括你购买宽带/流量的运营商,都可以“窃听”你们的数据,甚至还可以修改数据。

听起来不够直观?打个比方,近代时期,战场上打仗时,部队之间会通过电台进行交流。如果通过明文进行交流,那么非常危险,敌军可以打开电台进行窃听,偷取你的军事情报,这样的事也屡见不鲜了…那么他们是如何解决这个问题的呢?两个部队之间提前约定一个加密的方案,在传数据之前,先把它进行加密再传输,另一端收到数据之后,按照事先约定的方案进行解密,然后读取就可以了。这样即使敌军开始窃听,也只能听到加密后的情报,如果无法对其破解的话,得不到任何有效信息。

没错,这就是 HTTPS 的思想,浏览器在发送 HTTP 请求之前,先通过某种方式对其进行加密,然后再进行传输。服务器端收到数据之后,对其解密,读取真实内容,生成 HTTP 响应,同样对响应进行加密,然后传回给浏览器,浏览器收到数据之后,对其进行解密,得到真正的 HTTP 响应。这样就可以保证数据在传输过程中的安全性,无论是路由器还是运营商,都没有办法“窃听”你们的数据了。

说到这里,想必你已经知道 HTTPS 的一大作用了,它可以保证数据在互联网上传输的安全性,避免中间节点进行窃听和修改。

当然,聪明的你还可能会想到一些问题,例如:

  1. 战场上军队之间是提前约定好加密方案的,但是咱们任意一个浏览器都可以随时访问网页,没有办法提前约定加密方案呀,那是怎么做到的呢?
  2. 战场上经常出现敌军对另一方部队之间的电台加密进行破解的事情,破解完成之后,还是能够窃听到数据,那 HTTPS 的这个加密方案到底安全吗,会被破解吗?

别急,这些问题,你都可以在本文中得到答案。

HTTP + SSL = HTTPS

上面提到了对 HTTP 进行加密的思想。在 HTTPS 的具体实现中,这个加密方案即是大名鼎鼎的 SSL(Secure Sockets Layer)。

定义:SSL(Secure Sockets Layer)是一种安全协议,用于在互联网上保护数据的传输安全。它工作在传输层,主要功能是通过加密技术,保护不同计算机之间的数据传输过程,防止敏感数据被黑客窃取和篡改。SSL 协议可以用于保护网站的用户登录、信用卡支付、网上银行等敏感信息的传输,以及企业之间的机密数据的传输。SSL 协议目前已经被继承为 TLS(Transport Layer Security),是一种安全性更高的传输层协议。所以,下面我将统一以 TLS 为名称进行讲解。

首先,划重点,TLS 中有 Transport Layer,顾名思义,它一定是工作在传输层了。上面提到过,HTTP 是应用层协议,传输层和应用层的概念,想必大家应该知道吧,计算机网络的事实标准中,自顶向下可以分为五层:应用层、传输层、网络层、链路层、物理层…这是《计算机网络》的基础,这里不过多展开,不熟悉的同学,要回去重修一下课程了。

我们知道,TCP 协议里有三次握手,三次握手成功后连接才算建立,接下来才会真正开始传输数据。传统的 HTTP 协议中,三次握手成功之后,就会直接开始明文传输 HTTP 数据了。

那么 TLS 是什么时候开始发挥作用的呢?答案很简单,在三次握手之后,传输数据之前。

也就是说,在 TCP 协议中加入 TLS 之后,三次握手成功之后就不会再立刻开始传输数据了,而是紧接着开始 TLS 的建立过程,也被称为 TLS 握手。

TLS 握手是干嘛呢?或者说为什么需要 TLS 握手呢?上面提到,在战场上,两个部队之间会提前约定好加密的方案,例如面对面用纸互相写下加密方案,然后在一段时间之内的电台通信统一用这个加密方案,这样能一定程度上保证电台通信的安全性。但是 TLS 中我们并没有这样一个“面对面”的机会,咱们总不可能在访问网页之前,人肉跑到服务器的维护者那边去跟他约定加密方案吧。出于这个目的,TLS 握手便出现了。所以我们可以说,TLS 握手的目的是给通信双方约定一个安全的加密方案(可以理解为商量一个只有双方知道的加密密钥)

知道了 TLS 握手的目的,接下来我们需要知道它具体是怎么做的。首先,我们肯定不能直接明文传输加密方案(密钥),不然这个密钥在传输过程中就直接被第三方获取了,那么加密将没有任何意义。也就是说,TLS 握手需要做到:通信双方可以约定一个共同的加密方案(密钥),并且这个约定的过程(即 TLS 握手过程),即使被任何第三方窃听到,也无法解析出这个加密方案(密钥)

是不是听起来很神奇,那到底是怎么做到的呢?这就不得不提到密码学中非常经典的两个概念:对称加密和非对称加密。

对称加密和非对称加密

对称加密的特点是:约定一个共同的密钥,这个密钥可以用来加密数据,也可以用来解密数据,有点类似于上面提到的战场上的加密方案。

在这里插入图片描述

对称加密是 TLS 握手成功后,通信双方之间采用的数据加密方案。现在的主要问题是:通信双方如何安全的商量好这个对称密钥,防止密钥被其他人窃取?

这时就需要轮到非对称加密出场了。什么是非对称加密呢?与对称加密不同,非对称加密方案中,用户手握两把密钥,一把称为公钥,一把称为私钥,其中公/私钥都可以用来加密/解密数据,其特点为:用公钥加密后的数据,只有用私钥才能将其解开;用私钥加密后的数据,只有用公钥才能将其解开!

在这里插入图片描述

这里只介绍了非对称加密的特点,并没有介绍其原理,因为这属于密码学的范畴了,展开来讲又是一篇文章。

简单说说其思想吧,目前流行的非对称加密算法 RSA 基于的原理其实就一句话:我们目前还没有很好的办法对一个很大的数做因式分解,例如你在心里默默想一个很大的质数 p 和 质数 q,算出其乘积 n,那么向外公开 n 的话,外部人员是很难找出 p 和 q 的(只能暴力尝试,而当这样的数够大够多的时候,以现在的计算机算力也需要几百上千年的时间才能破解了)。对密码学感兴趣的同学,可自行进一步了解。

有了非对称加密,事情就变得有意思起来了。见下图,服务器端用非对称加密方案生成一对公/私钥,私钥掌握在自己手里,谁也不告诉;在 TLS 握手的过程中,服务器将自己的公钥交给浏览器端,浏览器端在心里默默想出一个对称加密的密钥后,将这个密钥用服务器端的公钥进行加密,然后再传回给浏览器端;浏览器端收到这个数据之后,用自己的私钥将其进行解密,就能够得到刚才浏览器心里默念的那个对称密钥了。这样这个问题就完美的解决了,两边可以心有灵犀的拿到这个对称密钥,而不用担心被任何第三方窃取到了。

在这里插入图片描述

这就是 TLS 握手的过程吗?不,当然没这么简单了,我们还没有考虑一个非常巧妙的攻击手段:中间人攻击。

中间人攻击

具体什么是中间人攻击呢?看下面这张图

在这里插入图片描述

假设现在我们从电脑上访问百度,如果有一个中间人在我的路由器端,或者运营商端,或者任何一个中间节点上截取了我的请求,刚不是提到服务器端需要返回给我们公钥吗,中间人他自己也生成一套公/私钥,然后将自己的公钥返回给我,这样我就与中间人之间建立了一条我以为“安全”的连接了,此时我以为我连接的是百度服务器,其实我连接的是中间人…那么此时中间人可以做任何事情了,如果他人品比较好的话,他可以默默当一个代理,我要访问百度,他就去帮我访问百度,然后把结果返回给我,勤勤恳恳做一个“中间商”。

当然,我们知道做这种攻击的人人品往往不会太好,所以他们可以做更坏的事情,例如伪造一个银行网页返回给我,让我填写账号和密码,这样的话…后果就不堪设想了。

那么如何防止中间人攻击呢?其中的核心就是:我们需要保证我们访问的就是目标服务器,例如,当我们访问百度时,我们需要确保在 TLS 握手时,给我们公钥的人就是百度,而不是任何其他人

那么这个应该如何去保证呢?这就不得不提到接下来的几个概念了,数字证书,以及证书权威机构(Certificate Authority,简称 CA)。

数字证书与 CA

数字证书是由证书权威机构(CA)颁发的一个用于证明身份的证书,当然其中还包含了该用户的公钥等信息。

例如还是以百度为例,假设百度需要给 www.baidu.com 这个域名申请一个数字证书,他需要在生成公钥/私钥后,将自身的信息(包括域名、公司名称、公钥信息等)发给某个证书权威机构(CA),让 CA 给自己颁发一个数字证书。

CA 需要验证百度的真实身份,并且他确实拥有 www.baidu.com 这个域名,一切都验证通过后,CA 才会给百度颁发这么一个数字证书。那么之后,不管是谁用浏览器访问 www.baidu.com 的时候,百度都会将刚才那个 CA 颁发的数字证书发送给用户,既可以用来自证身份,同时还顺便告诉了用户自己的公钥

到这里你可能还会有几个疑问:

  1. 数字证书如何保证不能伪造呢,难道中间人不能伪造一个数字证书发送给用户吗?
  2. 即使数字证书不能被伪造,从概念上看他是公开的,难道中间人不能直接把这个证书颁发给用户吗?

下面会一一回答这几个问题。正式回答之前,先来看看数字证书里究竟有哪些内容。

既然上面提到百度,我们就以百度为例,我们使用浏览器访问百度,可以在地址栏左边看到一个小锁,点击后,就可以查看百度的数字证书

在这里插入图片描述

在这里插入图片描述

上图中可以看到该证书的一些基本信息:

  • 颁发对象:这个证书是颁发给百度的,并且只对域名 (www.)baidu.com 有效
  • 颁发者:这个证书是由 GlobalSign 颁发的。(GlobalSign是一家全球知名的证书权威机构)
  • 有效期:这个证书的有效期是从 2022 年 7 月到 2023 年 8 月。(一旦过期,证书将不被信任)
  • 指纹:指纹是整张证书经过哈希计算后得到的特征值,主要与后面会提到的签名一起工作,起到防篡改的作用

当然,一张数字证书的内容远远不止于此,例如还包含了服务器的公钥,可以在“详细信息”中进行查看。

下面我们在证书详细信息中点击“导出”,将证书导出为 Base64 编码的单一证书,然后使用 openssl 对其进行解析和查看

$ openssl x509 -noout -text -in baidu.com.cer
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            44:17:ce:86:ef:82:ec:69:21:cc:6f:68
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign RSA OV SSL CA 2018
        Validity
            Not Before: Jul  5 05:16:02 2022 GMT
            Not After : Aug  6 05:16:01 2023 GMT
        Subject: C=CN, ST=beijing, L=beijing, OU=service operation department, O=Beijing Baidu Netcom Science Technology Co., Ltd, CN=baidu.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:aa:2f:cc:41:8d:25:ae:83:e9:f4:27:c4:00:b3:
                    39:6f:0e:98:2a:55:7d:07:e5:80:49:82:fa:d3:d3:
                    85:98:b5:df:7b:6f:bb:02:dd:ed:78:e4:0c:07:2b:
                    9e:1e:86:4b:f6:6a:86:58:d7:57:6f:21:59:11:d8:
                    6f:96:6e:d2:de:36:28:f6:b4:e3:ce:95:32:29:00:
                    c1:65:8e:69:b0:00:fe:52:37:f4:88:3f:8b:6d:0f:
                    bb:f0:ec:c5:c0:31:ef:ad:b5:0c:06:66:ad:be:dc:
                    43:13:c4:66:b0:5d:cf:56:53:e2:d1:96:82:1c:06:
                    bb:9b:5f:ed:60:8d:d2:ed:f3:d2:50:ee:bb:cd:b2:
                    36:97:c8:ce:7b:d2:4b:b7:5c:b4:88:ca:37:6e:8b:
                    ce:f9:96:fd:b4:f5:47:b5:20:77:bb:fc:a8:9d:81:
                    b2:6c:f8:c7:09:6a:dd:22:6e:83:3f:a7:53:df:f1:
                    da:2f:29:6b:22:c3:e9:1d:65:e8:c5:a0:ba:13:4e:
                    16:3f:03:93:f0:a5:59:8a:1a:80:e8:27:7d:49:23:
                    df:d1:f9:4b:97:b7:01:c4:19:f5:f1:c5:ff:91:33:
                    d0:a1:74:c6:ee:d4:cf:f6:38:0c:ed:bd:5e:aa:44:
                    fb:88:f7:7b:99:70:76:34:55:7e:55:d2:0f:9e:bf:
                    94:93
                    
    ... (中间省略)
   
    Signature Algorithm: sha256WithRSAEncryption
         63:21:07:23:47:06:eb:b3:7c:77:6c:df:bc:55:12:b9:f1:5e:
         6a:04:60:16:be:d0:0b:18:9c:94:0c:a8:82:08:25:0d:26:fb:
         dd:cb:fc:8c:27:d9:0c:fa:4a:b6:31:b6:67:f0:26:2c:0d:96:
         96:39:65:3f:d9:a1:ee:de:9c:10:4d:54:e1:c8:d6:a9:0e:77:
         db:00:e2:37:e3:3f:b4:9c:31:4f:ac:74:d3:22:12:53:36:d0:
         ef:18:07:2d:8e:d0:e6:91:b2:6c:4a:5e:39:53:14:58:4e:d1:
         50:04:c9:83:7e:0d:7b:15:96:87:11:d7:5d:4a:17:ac:aa:9f:
         84:e3:a8:24:9d:d6:17:77:26:8c:9f:7a:7b:18:da:39:2f:77:
         f7:2b:c7:23:b8:97:6f:c3:d1:72:4c:7e:fc:c6:0d:cc:73:38:
         19:81:fb:e7:c1:7a:e8:b9:1d:3a:05:dc:36:04:9b:f1:f0:e1:
         a6:47:a0:30:4f:55:90:6c:da:cf:9e:b2:76:12:11:a1:5c:b6:
         61:8d:15:a4:68:65:9a:57:2f:7a:6e:a3:1f:f5:b4:92:5a:3c:
         df:71:0a:cd:57:d4:d0:15:36:7e:ba:d5:03:25:27:45:b4:60:
         cd:2e:02:c1:0f:0a:e7:41:6f:58:69:20:9e:ad:47:52:1a:b5:
         e6:e5:8d:1d

可以看到,除了上面 Chrome 里显示的一些基本信息外,证书里还包含了几个重要信息:

  • 服务器端的公钥,即上面 RSA Public-Key 下面的那一长串数字,就是百度的公钥了。
  • 签名,证明数字证书有效的关键信息。如果把数字证书类比成一张合同的话,我们知道合同需要老板签字才算有效,同样,数字证书是需要 CA 签名才算有效的,这里的一长串字符就是 CA 对该证书的“签名”了。

我们知道合同上的签名是靠笔迹鉴定来确认真伪的,很明显这一长串字符里没有笔迹,那它是如何保证该签名是 CA 颁发的,而不是被其他人伪造的呢?

上面我们提到,每一张数字证书有一个指纹,是将整张证书经过哈希运算后得到的特征值。CA 作为权威机构,其本身也是有一对公钥/私钥的,它在颁发数字证书的时候,会用自己的私钥对证书的指纹进行加密,生成的这段加密数据,就是该证书的签名了!那么我们浏览器是如何验证证书的真伪呢?我们只需要使用 CA 的公钥对签名进行解密,看看得到的值是不是跟证书的指纹是一样的,这样就 OK 了,只要是一样,说明这个证书一定是 CA 颁发的。

那么,又有问题来了:我们浏览器是从哪里拿到 CA 的公钥呢?总不能还是通过网络传输吧,这样就有“套娃”的中间人攻击风险了。所以啊,我们的浏览器或操作系统已经内置了世界权威的 CA 的数字证书(证书里就包含了其公钥)了,点击浏览器的 设置 -> 隐私设置和安全性 -> 安全 -> 管理设备证书,可以查看当前系统内置的所有 CA 证书。

在这里插入图片描述

上图是我的电脑中内置的 CA 证书。刚刚提到了百度的数字证书是由 GlobalSign 颁发的,这里也可以验证,GlobalSign 是被我们的操作系统所信任的 CA,并且我们已经将它的证书内置在操作系统中了。因此现在我们可以认定说,这个证书是值得信任的,与我们建立连接的就是百度,不是别人。

你可能会想,如果中间人将百度真实的数字证书返回给我呢?中间人是没有百度的私钥的,所以当我们提取出证书中的公钥,并对心里想的密钥进行加密后,中间人是解不开这个密钥的,所以中间人无论如何也无法与我们建立连接。

好了,数字证书的内容已经全部讲述完毕了,最后回过头来复习下前面提到的两个问题:

1.数字证书如何保证自身不会被伪造?

数字证书中有一段签名,该签名是 CA 使用其私钥对证书指纹进行加密后得到的值,我们浏览器使用 CA 的公钥对该签名进行解密后,与该证书的指纹进行对比,就可以知道证书是否被篡改或者伪造了。

当然,这里要多提一嘴,我们作为客户端,需要保证自己的电脑里保存的都是值得信任的 CA 根证书,因为信任某 CA 就代表信任了该 CA 颁发的所有数字证书,如果有人/软件想在你的电脑里安装来历不明的 CA 证书,那你就要保持警惕了…

2.如果中间人直接把真实的数字证书返回给我,它能够成功与我建立连接吗?

答案是不行的。这个问题其实比较简单,刚刚提到,服务器端除了公钥外,自身还保存有一份私钥的,而中间人是拿不到这个私钥的,因为它被服务器雪藏起来,不会发送到互联网中的…那么如果中间人用服务器的证书返回给用户,用户采用服务器的公钥对自身默念出来的对称密钥进行加密后,返回给中间人的时候,中间人就一脸懵逼了,因为这个密钥它解不开呀,它没有私钥的,所以这个问题就完美解决了。

TLS 握手具体过程

最后,我们再完完整整讲一下 TLS 握手的具体流程。

在这里插入图片描述

上图来自 www.ssl.com ,展示了整个握手流程,我用大白话解释一下:

  1. 客户端向服务器发送 Client Hello 信息,告知自己想要建立一条 TLS 连接,并告知自己支持的加密算法。
  2. 服务器向客户端发送一个 Server Hello 的回应,并选择一个加密算法,同时给客户端发送自己的数字证书(包含服务器的公钥)。
  3. 客户端验证服务器发来的数字证书,验证通过后,在心里默默想出一个 pre-master 密钥(预主密钥),然后使用服务器的公钥,将预主密钥进行加密后,发送给服务器。
  4. 服务器用自己的私钥进行解密,得到预主密钥。
  5. 客户端和服务器都通过预主密钥,进行相同的计算后,得到后续通信时使用的对称加密密钥,称为 shared secret。
  6. 客户端和服务器端都分别用生成的 shared-secret 加密一段报文后,发送给对方,以验证对方能够成功收到信息并解密。

然后 TLS 就建立成功了,接下来双方都用这个 shared-secret 进行加密通信。

总结一下,HTTPS 的加密过程中其实既用到了非对称加密也用到了对称加密,其中握手过程使用的是非对称加密,主要目的是双方可以安全的协商一个统一的密钥,而真正的数据传输过程则使用的是对称加密,正是使用刚才商量的这个密钥。

你可能会问,为什么不全程使用非对称加密呢?因为对称加密效率更高,尤其是在大量数据的时候,对称加密比非对称加密整整快几个数量级,所以真正数据传输的过程选用了对称加密。

到这里,HTTPS 的原理就已经全部介绍完毕了

总结

最后,我们总结一下,HTTPS 解决了两个问题:

  1. 数据传输过程中的安全问题,因为它对数据进行了加密,只有浏览器和服务器可以对其进行解密。
  2. 浏览器对服务器的信任问题,数字证书以及其中的数字签名,保证了我们访问的就是我们想要访问的服务器,不可能被钓鱼网站欺骗,也不可能被中间人攻击所欺骗。

当然,保证以上安全的前提是我们的电脑本身没有被攻破,如果你的电脑被黑客攻击,装上了来历不明的根证书,那么 HTTPS 也不能保障你的安全了。

如果对你有帮助,就一键三连呗(点赞+收藏+关注),我会持续更新更多干货~~

  • 12
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿陌名!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值