【5.4k字+25张原创图】不信你看完还不懂HTTPS(图解HTTPS)

前言:

本文首发于我的博客,欢迎进来玩,增加点击量。

本文的行文思路来自最近看的一本书《图解HTTP》,所有流程图均由自己在Excalidraw上原创,如需引用,请标明出处,也欢迎在本文评论区留言探讨,如果对您有帮助,请不要吝啬您的点赞和收藏~

背景

都4202年了,互联网如此发达的现在,我们经历过的网站和 Web 应用也越来越多,而细心的你可能会发现,几乎每个我们经常使用的网站都使用 HTTPS 协议传输数据,原因在于 HTTPS 相较于 HTTP 能够提供更加安全的服务。 浏览器对于使用 HTTP 协议的网站都会加上⚠︎标志表示数据传输不安全,而对于使用 HTTPS 协议的网站则会表示安全。 那么是什么让各个公司都纷纷选用 HTTPS 呢?这就不得不提 HTTP 协议在安全性方面上的三个缺点了:

HTTP的缺点:

  1. 通信使用明文(不加密),内容可能会被窃听。
  2. 不验证通信方的身份,通信方有可能遭遇伪装。
  3. 无法证明报文的完整性,有可能接收到的报文已遭篡改。

HTTPS来解决HTTP的安全性问题:

针对上文提到的三个方面的问题,我们的 HTTPS 协议堂堂诞生!那么它是怎么解决这三个问题的呢?

  1. 会被窃听?数据加密! : HTTPS 通信不再使用明文,而是使用加密后的密文
  2. 会被伪装?数字证书! : HTTPS 通信双方通过数字证书机构(CA)颁布的数字证书来证明双方身份。
  3. 会被篡改?完整性保护! : HTTPS 通过摘要算法得到传输数据的摘要,如果数据被篡改,接收方算出的摘要将发生改变,接收方就知道传输数据已被篡改。

通过上面的介绍,我们也就可以回答这个经典问题了------------"什么是HTTPS?"

答:HTTP + 加密 + 认证 + 完整性保护 = HTTPS

HTTPS 是身披 SSL/TLS 外壳的 HTTP

其实 HTTPS 并非是应用层的一种新协议,只是在 HTTP 通信部分接口用 SSL (安全套接层)和 TLS (安全传输层协议)代替了而已:

  1. 通常情况下,HTTP 直接和 TCP 通信。
  2. 当使用 HTTPS 时,则变成 HTTP 先和 SSL/TLS 通信,再由 SSL 和 TCP 通信。所以也可以说:HTTPS = SSL/TLS + HTTP

SSL/TLS 是世界上应用最为广泛的网络安全技术,在 HTTP 采用了他们之后,也就拥有了加密 + 认证 + 完整性保护这些功能。而且他们还不仅可以用在 HTTP 上,他们也可以用在任何需要加密的应用层协议上,如 SMTP 、Telnet 等

数据加密解决明文传输被窃听问题

在对 SSL/TLS 进行讲解之前,我们先来浅浅地了解一下加密算法们,如有错误请一定指出。 ps:从本章开始,我们都将通信双方假定为客户端和服务器,并且通常由客户端充当发送方,服务器充当接收方。

为了防止传输数据被黑客所窃听,客户端与服务器之间需要对数据进行加解密处理,如图所示,客户端 使用加密算法明文 转变为密文 ,而服务器 接收到密文 后,使用解密算法 将密文转变回明文 ,这样即使在通信中途密文被窃听了,黑客也无法获得有效的信息

近代的加密方法中,加密算法是公开的,而密钥却是保密的 。加密和解密都会用到密钥,没有密钥就无法对密文进行解密,反过来说,任何人只需要持有密钥,就能进行解密了。我们一般将加密算法分为两大类:

  1. 对称加密:加密和解密时,使用相同的密钥。图中密钥A = 密钥B
  2. 非对称加密:加密和解密时,使用不同的密钥。图中密钥A ≠ 密钥B

对称加密

对称加密在加密和解密时,使用的是相同的密钥。 凯撒加密是一种最简单且最广为人知的加密算法,它是一种替换加密的技术:明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。

如上图,每个字母都向后偏移了4个字母 的位置。那对于对称加密来说,这个偏移量 就是密钥

当然,凯撒加密过于简单了,肯定不算是行之有效的加密算法。 为了增加解密的难度,对称加密内部又细分为流加密分组加密两种类型,现在常用的对称加密算法有** DES 、3DES 、 AES 、RC4 **等。这里就不过多展开了。

对称加密的优缺点
  • 优点:简单快捷、计算量小、加密速度快、加密效率高,一般是非对称加密算法的 100-10000 倍。
  • 缺点:在数据传送前,发送方和接收方必须商定好秘钥 ,然后双方保存好秘钥。如果一方的秘钥被泄露,那么加密信息也就不安全了 。所以在商定阶段 ,就很容易泄露密钥

非对称加密

对称加密在加密和解密时,使用的是一对 不同的密钥,分别是公开密钥(简称公钥)和私有密钥(简称私钥

  1. 私钥只能由一方安全保管,不能泄露。而公钥则可以发给任何请求它的人。
  2. 非对称加密使用这对密钥中的一个进行加密另一个则用来解密

如图所示,在商定阶段,客户端请求服务器的公钥,在数据传输节点,客户端用公钥加密,服务器用私钥解密。与对称加密不同的是,即使在商定阶段公钥被窃听了,黑客也几乎不可能根据公钥和密文解出明文。现在常用的非对称加密算法有:**RSA 、ECC(移动设备用)、Diffie-Hellman 、El Gamal 、DSA(数字签名用)**等。

非对称加密的优缺点
  • 优点:安全性更好,即使公钥暴露了也无所谓。
  • 缺点:存在大量的指数运算,加密和解密速度都非常慢,只适合对少量数据进行加密。

HTTPS 采用混合加密

前文已经介绍过了,如果使用对称加密,密钥容易泄露。如果使用不对称加密,密钥安全了,但速度可太慢了,完全满足不了当今网络传输数据量的需要。所以机智的 HTTPS 充分利用了两者各自的优势,采用了混合加密的方法:

  1. 商定阶段 使用非对称加密 :用公钥加密,私钥解密,确保下个阶段的密钥安全到达双方。
  2. 传输数据阶段 使用对称加密 :在确保密钥安全的情况下,就可以大胆使用对称加密提速了。 也就是说,用非对称加密算法传输密钥,用对称加密算法传输实际数据 。为了方便描述,我们将商定阶段传输的密钥称为共享密钥

数字证书解决 HTTP 通信方有可能遭遇伪装问题

只有混合加密还不够

在前文中,我们已经了解了混合加密的方式和共享密钥的存在。但是万一客户端和服务器之间,有黑客伪装成中间者(如 DNS服务器),即使是混合加密也会让密文加密的真实内容暴露,如图:

  1. 客户端发送的请求被黑客伪装的 DNS服务器 劫持,客户端向中间者请求公钥1
  2. 中间者正常转发请求公钥1的请求到服务器。
  3. 服务器响应公钥1给中间者。
  4. 中间者假装自己是服务器,给客户端响应原属于自己的公钥2
  5. 客户端用公钥2加密接下来要传输的共享密钥,向服务器(其实是中间者)发出。
  6. 中间者使用自己的私钥2解密得到共享密钥,至此共享密钥已经泄露
  7. 中间者使用先前获得的公钥1加密共享密钥
  8. 中间者将加密后的共享密钥发至服务器。
  9. 服务器用私钥1解密后也得到共享密钥
  10. 此后客户端和服务器之间再用共享密钥加密传输数据,由于共享密钥泄露,中间者将清清楚楚地知道传输内容 ,也就能随心所欲地篡改窃听了。

那么有没有办法能让客户端在第4步 得到公钥的时候,证明它是来自服务器而不是其他人的呢? 答:有!解决办法就是1数字证书`!

数字证书

如果有人突然问你一个问题,如何证明你是你自己呢?,那当然是靠身份证了。对于网站也是一样,如何证明你的网站是合法的而不是黑客假冒的呢?,这个时候就要靠数字证书啦。 就如同身份证的有效性是由国家权威机构保证的一样,我们网站的数字证书也需要权威的第三方机构来保证书的有效性,这样的机构我们就称为数字证书机构(简称CA机构CA)。 所以我们目前给自己网站申请使用 HTTPS 协议的时候,都需要去CA申请一份数字证书申请数字证书需要服务器提供申请者、域名、公钥等信息。

有了数字证书,当浏览器向目标网站服务器发起请求时,服务器只需要把数字证书返回给浏览器就能证明自己的合法性了。但是还不够,如果数字证书在传输过程中被挟持并篡改了,还是会出现中间者问题。

带数字签名的数字证书

为了解决上述问题,CA机构机智地使用了数字签名CA机构在向网站颁布数字证书之前,会在数字证书上签名,这个签名相当于------------来自CA机构的私钥加密后的数字证书摘要。而这个被加密后的摘要,在客户端浏览器中可以通过CA机构的公钥摘要算法验证其有效性。如图:

  1. 网站服务器用自己的公钥1CA机构申请数字证书
  2. CA机构通过审核之后,会生成一份证书明文,其中就包括了申请者的公钥和其他信息。
  3. CA机构利用一种摘要算法证书明文进行摘要,得到证书摘要
  4. CA机构用自己的私钥加密证书摘要得到数字签名
  5. CA机构数字签名证书明文合并,得到数字证书,并颁布给对应网站服务器。
  6. 客户端向服务器请求得到数字证书后,自行在浏览器上验证。

浏览器是怎么验证数字证书的呢?如图:

  1. 浏览器拿到数字证书之后,将其拆分为数字签名证书明文
  2. CA机构公钥解密数字签名,得到证书摘要1
  3. CA机构同种摘要算法处理证书明文,得到证书摘要2
  4. 比较以上两次操作得到的摘要,如果相同,则证明有效。反之则无效。

而 Chrome 浏览器一旦发现证书无效或者证书过期,则会提示如下警告:

至此,HTTP 通信方有可能遭遇伪装的问题也就解决了!

摘要算法解决传输数据被篡改问题

摘要算法又称哈希算法、散列算法。摘要也称哈希值,表示输入任意长度的数据,都会输出固定长度的数据

摘要算法具有以下特点:

  1. 压缩性:任意长度的数据,计算出的摘要长度都是固定的(如 MD5(32) 结果长度固定为128位)。
  2. 容易计算:从原数据计算出摘要很容易,消耗时间短
  3. 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的摘要都有很大区别。即:不同输入,绝大概率 计算出不同的摘要
  4. 同源性:相同的输入,相同的摘要算法,一定 会计算出相同的摘要
  5. 强抗碰撞:已知原数据和其摘要,想通过组合碰撞找到一个具有相同摘要的数据(即破解原数据)是非常困难的。
  6. 不可逆性:无法根据摘要反推出原文。

现在常用的摘要算法有:MD5、SHA1 、SHA256 、HAMC 、CMAC 等。其中 MD5 和 SHA1 都已经被破解了,要注意使用。

在数据传输中加入摘要

在 HTTPS 的数据传输过程中,客户端会将明文与通过明文生成的摘要1一齐发送至服务器,服务器收到明文后,会用与客户端相同的摘要算法 生成摘要2,比较以上两个摘要,就可以看出明文是否有被篡改过了。 上一句提到的"相同的摘要算法"是在通信双方 TLS 握手阶段商定的,我们之后会说到。

引入 HMAC 防止摘要也被篡改

通过上面的做法,我们大致可以防止明文被篡改了,但这样做还是存在一个问题:如果黑客在篡改明文的同时,也篡改了摘要,这要怎么办呢?

这个时候,所以 HTTPS 还引入一种优化方案:HMAC(消息认证码) 。定义 HMAC 需要一个散列函数(即 MD5 SHA 之类)和一个密钥(比如一个随机数密钥 ),也就是说此时摘要算法的输入变成了两部分:数据明文 + 随机数密钥 。需要注意的一点是,这个随机数密钥只能有通信双方知道,黑客是不可能知道的,所以该随机数密钥应该在商定阶段被确定。如图:由于黑客不可能这个随机数密钥,篡改的摘要3也就不正确了。

小结,引出 SSL/TLS 握手

说了这么多,让我们来总结一下 HTTPS 需要用到算法/密钥总共有什么吧:

  1. 传输数据,需要对称加密算法共享密钥
  2. 传输共享密钥需要非对称加密算法
  3. 防止被伪装身份,需要数字证书 。(数字证书中能取出服务器公钥
  4. 保证报文完整性,需要摘要算法
  5. 防止摘要被篡改,需要 HMAC 的随机数密钥

有这么多东西需要被商定 ,这些工作都是靠谁完成的呢?诶,这些全都是由 SSL/TLS 完成的。那 SSL/TLS 又是怎么完成商定的呢?我们继续往下看。

SSL/TLS 发展进程

SSLSecure Sockets Layer) 是网景公司(Netscape)设计的主要用于 Web 的安全传输协议,这种协议在 Web 上获得了广泛的应用。以下是摘取自权威文档部分发展历史:

  1. 1996 年,SSL3.0 问世,得到大规模应用(已于 2015 年弃用)。
  2. 1999 年,SSL3.1 被标准化,更新为 TLS1.0(Transport Layer Security)。所以有,TLS1.0 = SSL3.1。
  3. 现在主流的版本是 TLS1.2(2008 年发布)。
  4. 未来,可能是 TLS1.3 的时代(2018 年发布)。

所以在之后的篇章中,我统一用 TLS 称呼 SSL/TLS 协议和 TLS1.2 协议。 后文出现的WireShark抓包图片,需要下载WireShark抓包并进行环境变量配置。

TLS 握手

上文已经说过了,HTTPS = HTTP + TLS 。 这里的 TLS 指的就是 TLS 握手,它类似于 TCP 三次握手 。 在 TLS 握手的过程中,通信双方交换消息以相互确认对方身份 ,并确立它们所要使用的 TLS 版本密码套件等等。

TLS 四次握手 发生在 TCP 三次握手之后,HTTP 传输数据之前。

第一次握手

1. Client Hello

Client HelloTLS 四次握手的第一个步骤,表示客户端向服务端发起了一个 TLS握手 请求,本次报文内容主要包括:

  1. 客户端支持的 TLS 版本 :客户端将自己所支持的TLS版本告知服务器,服务器做选择,如 TLS 1.2
  2. 客户端随机数 :客户端随机生成的一个数,后续用来生成共享密钥随机数密钥
  3. 客户端支持的加密套件Cipher suite ):客户端将自己支持的所有 加密套件做成列表告知服务器,服务器做选择,每个加密套件格式如下图:

第二次握手

2. Server Hello

服务器接收到 "Client Hello" 后,也进入TLS握手流程,连着发送三个响应客户端的响应,第一个响应内容主要包括:

  1. 服务器选择的 TLS 版本 :服务器做出选择。
  2. 服务器随机数 :服务器随机生成的一个数,后续用来生成共享密钥随机数密钥
  3. 服务器选择的加密套件 :服务器选择一个加密套件。
3. Certificate

服务器主持的第二次握手过程中,还需要将包含服务器公钥数字证书也发给客户端。

4. Server Hello Done

服务器发送此报文表示:自己已将所有预计商定的信息都发送完毕,第二次握手结束。

第二次握手补充: Server Key Exchange

经提醒,如果服务器数字证书没有足够的信息,不能让客户端完成pre-master的密钥交换时,服务器会在 "Server Hello" 后,立即发送 "Server Key Exchange"来补充信息, 主要是面向安全的几种密钥协商算法,列表如下:

  1. DHE_DSS
  2. DHE_RSA
  3. DH_anon
  4. ECDHE_ECDSA
  5. ECDHE_RSA
  6. ECDH_anon

第三次握手(需先验证数字证书

客户端收到服务器第二次握手的信息后,会验证其数字证书是否合法 ,如果证书合法,则进行第三次握手

5. Client Key Exchange

证书验证通过之后,客户端会生成pre-master(前主密钥),不过会因不同的算法套件而有差异:

  1. ECDHE会传递一个随机生成的client params
  2. RSA会随机生成pre-master,然后用服务器公钥加密后传递。

此时,客户端已经拥有:客户端随机数服务器随机数pre-masterclient params,客户端将用此三者结合生成master secret(主密钥),master secret会被用来生成共享密钥随机数密钥

6. Change Cipher Spec

通知服务器,后续客户端发送的消息都将采用对称加密通信。

7. Finished

客户端会将此前生成的共享密钥随机数密钥用在此处加密报文,送给服务器解读。如果服务器能解读,说明此前的商定阶段成功完成。 至此,第三次握手结束。

第四次握手

第四次握手之前,服务器需要从之前第5步:"Client Key Exchange"中,提取出来client params或用服务器私钥解密得到pre-master。 此时,服务器也拥有:客户端随机数服务器随机数pre-masterclient params。那它也能将三者结合生成和客户端一模一样master secret,再用它生成共享密钥随机数密钥

然后服务器进入第四次握手流程,它也会执行和客户端第三次握手时一模一样的操作,将加密报文送给客户端解读。如果客户端能解读,说明 TLS 四次握手 全阶段完成。

8. Change Cipher Spec

与第6步一致。

9. Finished

与第7步一致。

TLS握手结束

至此 TLS 握手过程圆满结束!如果还看不明白的同学,建议重看上面每一步的解释并结合着这张图慢慢理解,相信你们可以的。其实不难看出,TLS 握手的整个流程就是为了:

  1. 确定所使用的TLS版本,加密算法,摘要算法。
  2. 确保通信双方能安全 地生成一模一样的共享密钥随机数密钥

总结:

写这篇文章的主要原因是,最近在看书时发现自己以前整理的 HTTPS 笔记真的非常片面,所以才诞生了系统地重新整理一遍 HTTPS 知识的念头。当然,本篇文章的内容也仅够科普使用,如果想要更深入了解 HTTPS ,可以去详细读读《HTTPS权威指南》

仅当抛砖引玉,有错误请指出!有帮助请不要吝啬你们的点赞和收藏~

相关推荐
Gworg12 小时前
创建HTTPS网站
安全·https·ssl
木子_lishk15 小时前
gateway 支持同时使用 https 和 http访问
https·gateway
网络安全-老纪1 天前
iOS应用网络安全之HTTPS
web安全·ios·https
lxkj_20242 天前
修改ffmpeg实现https-flv内容加密
网络协议·https·ffmpeg
千羽星弦2 天前
Apache和HTTPS证书的生成与安装
网络协议·https·apache
可涵不会debug2 天前
【Linux|计算机网络】HTTPS工作原理与安全机制详解
linux·网络协议·http·网络安全·https
lu云之东2 天前
Harbor2.11.1生成自签证和配置HTTPS访问
网络协议·http·docker·https·harbor
helloWorldZMY2 天前
超文本传输协议(HTTP)与超文本传输安全协议(HTTPS)
网络协议·计算机网络·http·https
დ旧言~3 天前
【网络】数据链路层协议——以太网,ARP协议
开发语言·网络·网络协议·http·https·php
vvw&3 天前
在 Ubuntu 上使用 Traefik Proxy 为 Docker 容器设置反向代理
linux·运维·ubuntu·docker·https·反向代理·traefik proxy