HTTP/HTTPS详解
1、HTTP篇
1.1、HTTP概述
1、互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
2、超文本传输协议”,它可以拆成三个部分,分别是:“超文本”“传输”和“协议”。我们可以逐个解析,理解了这三个词,我们也就明白了什么是 HTTP。

- 首先,HTTP 是一个协议。不过,协议又是什么呢?其实“协议”并不仅限于计算机世界,现实生活中也随处可见。例如,你在刚毕业时会签一个“三方协议”,找房子时会签一个“租房协议”,公司入职时还可能会签一个“保密协议”,工作中使用的各种软件也都带着各自的“许可协议”。
刚才说的这几个都是“协议”,本质上与 HTTP 是相同的,那么“协议”有什么特点呢?
- 第一点,协议必须要有两个或多个参与者,也就是“协”。如果只有你一个人,那你自然可以想干什么就干什么,想怎么玩就怎么玩,不会干涉其他人,其他人也不会干涉你,也就不需要所谓的“协议”。但是,一旦有了两个以上的参与者出现,为了保证最基本的顺畅交流,协议就自然而然地出现了。
- 第二点,协议是对参与者的一种行为约定和规范,也就是“议”。协议意味着有多个参与者为了达成某个共同的目的而站在了一起,除了要无疑义地沟通交流之外,还必须明确地规定各方的“责、权、利”,约定该做什么不该做什么,先做什么后做什么,做错了怎么办,有没有补救措施等等。
- 接下来我们来看 HTTP 字面里的第二部分:“传输”。计算机和网络世界里有数不清的各种角色:CPU、内存、总线、磁盘、操作系统、浏览器、网关、服务器等等,这些角色之间相互通信也必然会有各式各样、五花八门的协议,用处也各不相同,例如广播协议、寻址协议、路由协议、隧道协议、选举协议等等。
- HTTP 是一个“传输协议”,所谓的“传输”(Transfer)其实很好理解,就是把一堆东西从 A 点搬到 B 点,或者从 B 点搬到 A 点,即“A<===>B”。别小看了这个简单的动作,它也至少包含了两项重要的信息。
- 第一点,HTTP 协议是一个“双向协议”。也就是说,有两个最基本的参与者 A 和 B,从 A 开始到 B 结束,数据在 A 和 B 之间双向而不是单向流动。通常我们把先发起传输动作的 A 叫做请求方,把后接到传输的 B 叫做应答方或者响应方。拿我们最常见的上网冲浪来举例子,浏览器就是请求方 A,网易、新浪这些网站就是应答方 B。双方约定用 HTTP 协议来通信,于是浏览器把一些数据发送给网站,网站再把一些数据发回给浏览器,最后展现在屏幕上,你就可以看到各种有意思的新闻、视频了。
- 第二点,数据虽然是在 A 和 B 之间传输,但并没有限制只有 A 和 B 这两个角色,允许中间有“中转”或者“接力”。这样,传输方式就从“A<===>B”,变成了“A<=>X<=>Y<=>Z<=>B”,A 到 B 的传输过程中可以存在任意多个“中间人”,而这些中间人也都遵从 HTTP 协议,只要不打扰基本的数据传输,就可以添加任意的额外功能,例如安全认证、数据压缩、编码转换等等,优化整个传输过程。
- 最后我们终于可以看到 HTTP 字面里的第三部分:“超文本”。既然 HTTP 是一个“传输协议”,那么它传输的“超文本”到底是什么呢?我还是用两点来进一步解释。所谓“文本”(Text),就表示 HTTP 传输的不是 TCP/UDP 这些底层协议里被切分的杂乱无章的二进制包(datagram),而是完整的、有意义的数据,可以被浏览器、服务器这样的上层应用程序处理。在互联网早期,“文本”只是简单的字符文字,但发展到现在,“文本”的涵义已经被大大地扩展了,图片、音频、视频、甚至是压缩包,在 HTTP 眼里都可以算做是“文本”。所谓“超文本”,就是“超越了普通文本的文本”,它是文字、图片、音频和视频等的混合体,最关键的是含有“超链接”,能够从一个“超文本”跳跃到另一个“超文本”,形成复杂的非线性、网状的结构关系。对于“超文本”,我们最熟悉的就应该是 HTML 了,它本身只是纯文字文件,但内部用很多标签定义了对图片、音频、视频等的链接,再经过浏览器的解释,呈现在我们面前的就是一个含有多种视听信息的页面。
OK,经过了对 HTTP 里这三个名词的详细解释,下次当你再面对面试官时,就可以给出比“超文本传输协议”这七个字更准确更有技术含量的答案:“HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范”。
1.2、HTTP发展历程
- HTTP/0.9
1991 年 HTTP(HyperText Transfer Protocol,超文本传输协议)正式诞生,当时的版本是 0.9。从名字可以看出,该协议的作用是传输传输超文本内容 HTML。
协议定义了客户端发起请求、服务端响应请求的通信模式。请求报文内容只有 1 行:
GET + 请求的文件路径
服务端收到请求后返回一个以 ASCII 字符流编码的 HTML 文档。

HTTP/0.9 虽然简单,但是它充分验证了 Web 服务的可行性:
把简单的系统变复杂,要比把复杂的系统变简单容易得多。
- HTTP/1.0
随着互联网的发展以及浏览器的出现,单纯的文本内容已经无法满足用户需求了,浏览器希望通过 HTTP 来传输脚本、样式、图片、音频和视频等不同类型的文件,所以在 1996 年 HTTP 更新的 1.0 版本中引入了如下特性:
- 增加了 HEAD、POST 等新方法
- 增加了响应状态码,标记可能的错误原因
- 引入了协议版本号概念
- 引入了 HTTP Header(头部)的概念,让 HTTP 处理请求和响应更加灵活
- 传输的数据不再局限于文本
其中最核心的改变是增加了头部设定,头部内容以键值对的形式设置。请求头部通过 Accept 字段来告诉服务端可以接收的文件类型,响应头部再通过 Content-Type 字段来告诉浏览器返回文件的类型。
头部字段不仅用于解决不同类型文件传输的问题,也可以实现其他很多功能如缓存、认证信息等。

- HTTP/1.1
随着互联网的迅速发展,HTTP/1.0 也已经无法满足需求,最核心的就是连接问题。
具体来说就是 HTTP/1.0 每进行一次通信,都需要经历建立连接、传输数据和断开连接三个阶段。当一个页面引用了较多的外部文件时,这个建立连接和断开连接的过程就会增加大量网络开销。
为了解决 HTTP/1.0 的问题,1999 年推出的 HTTP/1.1 有以下特点:
- 长连接(Connection:keep-alive):引入了 TCP 连接复用,即一个 TCP 默认不关闭,可以被多个请求复用。
- 并发连接:对一个域名的请求允许分配多个长连接(缓解了长连接中的「队头阻塞」问题)。
- 引入管道机制,一个 TCP 连接,可以同时发送多个请求。(响应的顺序必须和请求的顺序一致,因此不常用)。
- 增加了 PUT、DELETE、OPTIONS、PATCH 等新的方法。
- 新增缓存字段(cache-control E-tag)。
- 请求头中引入了 range 字段,支持断点续传。
- 允许响应数据分块(chunked),利于传输大文件。
- 强制要求 Host 头,让互联网主机托管成为可能。

HTTP/1.1 与 HTTP/1.0 的一个重要区别是:
HTTP/1.1 是一个“正式的标准”
此后互联网上所有的浏览器、服务器、网关、代理等,只要用到 HTTP 协议,就必须严格遵守这个标准。
- HTTP/2
HTTP/1.1 通过长连接减少了大量创建/断开连接造成的性能消耗,但是它的并发能力受到限制,表现在两个方面:
- HTTP/1.1 中使用持久连接时,一个连接中同一时刻只能处理一个请求。当前的请求没有结束之前,其他的请求只能处于阻塞状态,这种情况被称为「队头阻塞」
- 浏览器为了减轻服务器的压力,限制了同一个域名下的 HTTP 连接数,即 6 ~ 8 个
2015 年正式发布的 HTTP/2 默认不再使用 ASCII 编码传输,而是改为二进制数据,来提升传输效率。
客户端在发送请求时会将每个请求的内容封装成不同的带有编号的二进制帧(Frame),然后将这些帧同时发送给服务端。服务端接收到数据之后,会将相同编号的帧合并为完整的请求信息。同样,服务端返回结果、客户端接收结果也遵循这个帧的拆分与组合的过程。
有了二进制分帧后,对于同一个域,客户端只需要与服务端建立一个连接即可完成通信需求,这种利用一个连接来发送多个请求的方式称为「多路复用」。每一条路都被称为一个 stream(流)。
HTTP/2.0 的主要改动包括:
- 数据通过二进制协议传输,不再是纯文本。
- 多路复用,废弃了 1.1 中的管道。
- 使用专用算法压缩头部,减少数据传输量。
- 通过设置数据帧的优先级,让服务器优先处理某些请求。
- 允许服务器主动向客户推送数据。
- 头部字段全部改为小写;引入了伪头部的概念,出现在头部字段之前,以冒号开头。
- 增强了安全性,“事实上”要求加密通信。

HTTP/2.0 虽然已经发布了 6 年,不过由于 HTTP/1.1 实在太过经典和强势,目前 HTTP/2.0 的普及率还比较低,仍然有很多网站使用的是 HTTP/1.1 版本。
- HTTP/3
看到这里,你可能会问了:“HTTP/2 这么好,是不是就已经完美了呢?”答案是否定的,这一次还是 Google,而且它要“革自己的命”。在 HTTP/2 还处于草案之时,Google 又发明了一个新的协议,叫做 QUIC,而且还是相同的“套路”,继续在 Chrome 和自家服务器里试验着“玩”,依托它的庞大用户量和数据量,持续地推动 QUIC 协议成为互联网上的“既成事实”。“功夫不负有心人”,当然也是因为 QUIC 确实自身素质过硬。在去年,也就是 2018 年,互联网标准化组织 IETF 提议将“HTTP over QUIC”更名为“HTTP/3”并获得批准,HTTP/3 正式进入了标准化制订阶段,也许两三年后就会正式发布,到时候我们很可能会跳过 HTTP/2 直接进入 HTTP/3。
- HTTP 1.0和HTTP 1.1的区别
长连接
HTTP 1.1支持长连接和请求的流水线操作。长连接是指不在需要每次请求都重新建立一次连接,HTTP 1.0默认使用短连接,每次请求都要重新建立一次TCP连接,资源消耗较大。请求的流水线操作是指客户端在收到HTTP的响应报文之前可以先发送新的请求报文,不支持请求的流水线操作需要等到收到HTTP的响应报文后才能继续发送新的请求报文。
缓存处理
在HTTP 1.0中主要使用header中的If-Modified-Since,Expires作为缓存判断的标准,HTTP 1.1引入了Entity tag,If-Unmodified-Since, If-Match等更多可供选择的缓存头来控制缓存策略。
错误状态码
在HTTP 1.1新增了24个错误状态响应码
HOST域
在HTTP 1.0 中认为每台服务器都会绑定唯一的IP地址,所以,请求中的URL并没有传递主机名。但后来一台服务器上可能存在多个虚拟机,它们共享一个IP地址,所以HTTP 1.1中请求消息和响应消息都应该支持Host域。
带宽优化及网络连接的使用
在HTTP 1.0中会存在浪费带宽的现象,主要是因为不支持断点续传功能,客户端只是需要某个对象的一部分,服务端却将整个对象都传了过来。在HTTP 1.1中请求头引入了range头域,它支持只请求资源的某个部分,返回的状态码为206。
HTTP 2.0的新特性
- 新的二进制格式:HTTP 1.x的解析是基于文本,HTTP 2.0的解析采用二进制,实现方便,健壮性更好。
- 多路复用:每一个request对应一个id,一个连接上可以有多个request,每个连接的request可以随机混在一起,这样接收方可以根据request的id将request归属到各自不同的服务端请求里。
- header压缩:在HTTP 1.x中,header携带大量信息,并且每次都需要重新发送,HTTP 2.0采用编码的方式减小了header的大小,同时通信双方各自缓存一份header fields表,避免了header的重复传输。
- 服务端推送:客户端在请求一个资源时,会把相关资源一起发给客户端,这样客户端就不需要再次发起请求。
1.3、HTTP状态码
- 1xx:提示信息,表示目前是协议处理的中间状态,还需要后续的操作
- 2xx:成功,保温已经收到并被正确处理
- 200 // OK 是最常见的成功状态码,表示一切正常,如果是非
HEAD请求,服务器返回的响应头都会有 body 数据。 - 204 // No Content 也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
- 206 // Partial Content 是应用于HTTP分块下载或断电续传,表示响应返回的body数据并不是资源的全部,而是其中一部分,也是服务器处理成功的状态
- 200 // OK 是最常见的成功状态码,表示一切正常,如果是非
- 3xx:重定向,资源位置发生变动,需要客户端重新发送请求,这类状态码表示客户端请求的资源发送了变动,需要客户端用新的URL重新发送请求获取资源,也就是重定向
- 301 // 表示永久重定向,说明请求的资源已经不存在了,需改用新的URL再次访问
- 302 // 表示临时重定向,说明请求的资源还在,但暂时需要用另一个URL来访问
- 304 // 不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓冲重定向,用于缓存控制
- 4xx:客户端错误,请求报文有误,服务器无法处理,这类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义
- 400 // 表示客户端请求的报文有错误,但知识笼统的错误
- 403 // 表示服务器禁止访问资源,并不是客户端的请求出错
- 404 // 表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端
- 5xx:服务器错误,服务器在处理请求时内部发生了错误,类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码
- 500 // 是个笼统通用的错误码,服务器发生了什么错误并不知道
- 501 // 表示客户端请求的功能还不支持,类似“即将开业,敬请期待” 的意思
- 502 // 通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误
- 503 // 表示服务器当前很忙,暂时无法响应服务器,类似“网络服务正忙,请稍后重试”的意思。
1.4、HTTP建立和断开连接
1.4.1、建立连接
- 先通过域名系统(Domain Name System,DNS)查询将域名转换为 IP 地址。即将 xxx.com 转换为 xxx.xxx.xxx.xx这一过程。
- 通过三次握手建立 TCP 连接。(上个章节已详细介绍:)
- 发起 HTTP 请求。
- 目标服务器接收到 HTTP 请求并处理。
- 目标服务器往浏览器发回 HTTP 响应。
- 浏览器解析并渲染页面。
下图中的 RTT 为往返时延(Round-Trip Time: 往返时延。表示从发送端发送数据开始,到发送端收到来自接收端的确认,总共经历的时延)。

1.4.2、断开连接
所有 HTTP 客户端(浏览器)、服务器都可在任意时刻关闭 TCP 连接。通常会在一条报文结束时关闭连接,但出错的时候,也可能在首部行的中间或其他任意位置关闭连接。
1.5、HTTP的请求与响应
1.5.1、HTTP的常见请求方式
- get:向服务端获取资源,所以查询操作一般用get。
- post:向服务端提交请求字段,创建操作使用 post,该操作不是幂等的,多次执行会导致多条数据被创建。
- put:修改指定URL的资源,如果资源不存在,则进行创建,修改操作一般使用 put,在http中,put 被定义成幂等的,多次操作会导致前面的数据被覆盖。
- patch:局部修改URL所在资源的数据,是对put的补充。
- delete:删除指定URL的资源。
- head:获取响应报文的首部,即获得URL资源的头部。
- options:询问服务器支持哪些方法,响应头中返回 Allow: GET、POST、HEAD。
- trace:追踪路径,主要用于测试或诊断;在请求头中在Max-Forwards字段设置数字,每经过一个服务器该数字就减一,当到0的时候就直接返回,一般通过该方法检查请求发送出去是否被篡改。
1.5.2、GET和POST请求的区别
- 功能:get一般用来从服务器上面获取资源,post一般用来更新服务器上面的资源。
- 幂等性:get 是幂等的,post 为非幂等的。
- 安全性:get 请求的参数会明文附加在URL之后,而 post 请求提交的数据则被封装到请求体中,相对更安全。
- 传输数据量的大小:get请求允许发送的数据量比较小,大多数浏览器都会限制请求的url长度在2048个字节,而大多数服务器最多处理64K大小的url;而post请求提交的数据量则是没有大小限制的。
- 参数的数据类型:GET只接受ASCII字符,而POST没有限制。
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- get请求可以被缓存,可以被保留在浏览器的历史记录中;post请求不会被缓存,不会被保留在浏览器的历史记录中。
1.5.3、HTTP报文分析
HTTP 报文由请求行、首部、实体主体组成,它们之间由“回车换行符”分隔开。
注意:实体包括首部(也称为实体首部)和实体主体,sp 即是空格 space。

请求行和首部是由 ASCII 文本组成的,实体主体是可选的,可以为空也可以是任意二进制数据。请求报文和响应报文的格式基本相同。
- 请求报文格式:
<method> <request-URL> <version>
<headers>
<entity-body>- 响应报文格式:
<version> <status> <reason-phrase>
<headers>
<entity-body>- 一个请求或响应报文由以下字段组成:
- 请求方法,客户端希望服务器对资源执行的动作。
- 请求 URL,命名了所请求的资源。
- 协议版本,报文所使用的 HTTP 版本。
- 状态码,这三位数字描述了请求过程中所发生的情况。
- 原因短语,数字状态码的可读版本(例如上面的响应示例跟在 200 后面的 OK,一般按规范写最好)。
- 首部,可以有零或多个首部。
- 实体的主体部分,可以为空也可以包含任意二进制数据。
- 一个 HTTP 请求示例:
GET /2.app.js HTTP/1.1
Host: 118.190.217.8:3389
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36
Accept: */*
Referer: http://118.190.217.8:3389/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9- 一个 HTTP 响应示例:
HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sat, 07 Mar 2020 03:52:30 GMT
ETag: W/"253e-170b31f7de7"
Content-Type: application/javascript; charset=UTF-8
Vary: Accept-Encoding
Content-Encoding: gzip
Date: Fri, 15 May 2020 05:38:05 GMT
Connection: keep-alive
Transfer-Encoding: chunked1.6、cookie和session的区别
众所周知,HTTP协议是无状态协议,自身不对请求和响应直接的通信状态进行保存,但有些场景下我们需要保存,但有些场景下我们需要保存用户的登录信息,所有就引入了cookie和session来管理状态。
- 保存位置与安全性:cookie保存在客户端,session保存在服务端,所以在安全性上面,cookie存在安全隐患,可以通过拦截或本地文件找到cookie后进行攻击,而session相对更加安全。因此,可以将登陆信息等重要信息存放为session中;其他信息如果需要保留,可以放在cookie中。
- 存储容量:单个cookie最大只允许4KB,一个站点最多保存20个Cookie;session没有大小限制,个数只跟服务器的内存大小有关。
- 有效期与实现机制:cookie可长期有效存在;session依赖于cookie,过期时间默认为-1,只需关闭窗口该 session 就会失效。每个客户端对应一个session ,客户端之间的 session 相互独立;
- cookie:cookie是一小段的文本信息,当客户端请求服务器时,如果服务器需要记录该用户状态,就在响应头中向客户端浏览器颁发一个Cookie,而客户端浏览器会把cookie保存起来。当再次请求该网站时,浏览器把请求的网站连同该cookie一起提交给服务器,服务器会检查该cookie,以此来辨认用户状态。
- session:当客户端请求服务器时,都会带上cookie,cookie里面一般都会有一个JSESSIONID,服务器就按照 JSESSIONID 来找到对应的 session;如果客户端请求不包含 JSESSIONID,则为此客户端创建session并生成相关联的JSESSIONID,并将这个JSESSIONID在本次响应中返回给客户端保存。客户端保存这个 JSESSIONID 的方式可以使用cookie机制。若浏览器禁用Cookie的话,可以通过 URL重写机制 将JSESSIONID传回服务器。
1.7、输入网址到获得页面的过程
- 解析url,获取url中包含的域名。
- 通过DNS系统查询域名对应的IP。

通过DNS系统查询域名对应的IP的具体步骤:
① 操作系统先查本地 hosts文件 中是否有记录,如果有,则直接返回相对应映射的IP地址。
② 如果本地hosts文件中没有配置,则主机向自己的本地 DNS 服务器 发送查询报文,如果本地DNS服务器缓存中有,将直接返回结果。
③ 如果本地服务器缓存中没有,则从内置在内部的根服务器列表(全球13台,固定的IP地址)中选一个发送查询报文。
④ 根服务器解析域名中的后缀名,告诉本地服务器负责该后缀名的所有顶级服务器列表。
⑤ 本地服务器选择其中一个顶级域服务器发送查询请求,顶级域服务器拿到域名后继续解析,返回对应域的所有权威服务器列表。
⑥ 本地服务器再向返回的权威服务器发送查询报文,最终会从某一个权威服务器上得到具体的 IP 地址。
⑦ 主机返回结果IP。
浏览器得到域名对应的IP地址之后,向服务器发起三次握手请求简历TCP连接。
TCP连接建立起来后,浏览器向服务器发送HTTP请求,如果HTML文件在缓存中,浏览器则直接返回,如果没有,就去后台拿。
① 浏览器首次加载资源成功时,服务器返回200,此时浏览器不仅将资源下载下来,而且把response的header(里面的date属性非常重要,用来计算第二次相同资源时当前时间和date的时间差)一并缓存。
② 下一次加载资源时,首先要经过强缓存的处理,cache-control的优先级最高,比如cache-control:no-cache,就直接进入到协商缓存的步骤了,如果cache-control:max-age=xxx,就会先比较当前时间和上一次返回200时的时间差,如果没有超过max-age,命中强缓存,不发请求直接从本地缓存读取该文件(这里需要注意,如果没有cache-control,会取expires的值,来对比是否过期),过期的话会进入下一个阶段,协商缓存。
③ 协商缓存阶段,则向服务器发送header带有If-None-Match和If-Modified-Since的请求,服务器会比较Etag,如果相同,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200。
④ 协商缓存第二个重要的字段是,If-Modified-Since,如果客户端发送的If-Modified-Since的值跟服务器端获取的文件最近改动的时间,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200。
服务器接收到请求后,根据路径参数映射到特定的处理器进行处理,并将处理结果以及响应的视图返回给浏览器。
浏览器解析视图,并根据请求到的资源、数据进行渲染页面,最终向用户呈现一个完整的页面。
- 构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree)。
- 构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树。
- 执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件)。
- 构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree)。
- 渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。
- 布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置。
- 绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成。
2、HTTPS篇
2.1、HTTPS概述
- HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
- HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
2.2、HTTPS工作过程(加密解密方式)
HTTPS加密过程:
- 客户端向服务端发起第一次握手请求,告诉服务端客户端所支持的SSL的指定版本、加密算法及密钥长度等信息。
- 服务端将自己的公钥发给数字证书认证机构,数字证书认证机构利用自己的私钥对服务器的公钥进行数字签名,并给服务器颁发公钥证书。
- 服务端将证书发给客户端。
- 客服端利用数字认证机构的公钥,向数字证书认证机构验证公钥证书上的数字签名,确认服务器公开密钥的真实性。
- 客户端使用服务端的公开密钥加密自己生成的对称密钥,发给服务端。
- 服务端收到后利用私钥解密信息,获得客户端发来的对称密钥。
- 通信双方可用对称密钥来加密解密信息。
流程图如下:


虽然HTTPS并非绝对的安全,掌握根证书的机构,掌握加密算法的组织同样可以进行中间人形式的攻击,但是HTTPS仍是现行架构下最安全的解决方案,它大幅增加了中间人攻击的成本。相对而言还是比较安全的。
2.3、CA证书的申请及其使用过程
那就先来说说对称加密和非对称加密区别及优缺点。
2.3.1、对称加密与非对称加密
- 对称加密
- 对称加密指加密和解密使用同一密钥,优点是运算速度快,缺点是如何安全将密钥传输给另一方。常见的对称加密算法有DES、AES等等。
- 非对称加密
- 非对称加密指的是加密和解密使用不同的密钥,一把公开的公钥,一把私有的私钥。公钥加密的信息只有私钥才能解密,私钥加密的信息只有公钥才能解密。优点解决了对称加密中存在的问题。缺点是运算速度较慢。常见的非对称加密算法有RSA、DSA、ECC等等。
- 非对称加密的工作流程:A生成一对非堆成密钥,将公钥向所有人公开,B拿到A的公钥后使用A的公钥对信息加密后发送给A,经过加密的信息只有A手中的私钥能解密。这样B可以通过这种方式将自己的公钥加密后发送给A,两方建立起通信,可以通过对方的公钥加密要发送的信息,接收方用自己的私钥解密信息。
- 非对称加密的优缺点
- 非对称加密的优点:
- 非对称加密采用公有密匙和私有密匙的方式,解决了http中消息保密性问题,而且使得私有密匙泄露的风险降低。
- 因为公匙加密的消息只有对应的私匙才能解开,所以较大程度上保证了消息的来源性以及消息的准确性和完整性。
- 非对称加密的缺点:
- 非对称加密时需要使用到接收方的公匙对消息进行加密,但是公匙不是保密的,任何人都可以拿到,中间人也可以。那么中间人可以做两件事,第一件是中间人可以在客户端与服务器交换公匙的时候,将客户端的公匙替换成自己的。这样服务器拿到的公匙将不是客户端的,而是中间人的。服务器也无法判断公匙来源的正确性。第二件是中间人可以不替换公匙,但是他可以截获客户端发来的消息,然后篡改,然后用服务器的公匙加密再发往服务器,服务器将收到错误的消息。
- 非对称加密的性能相对对称加密来说会慢上几倍甚至几百倍,比较消耗系统资源。正是因为如此,https将两种加密结合了起来。
为了解决非对称加密带来的问题,就必须引入数字证书与数字签名
2.3.2、CA签发证书
CA签发证书及客户端校验服务端的数字证书的过程:

- CA签发证书过程
- ⾸先 CA 会把持有者的公钥、⽤途、颁发者、有效时间等信息打成⼀个包,然后对这些信息进⾏ Hash 计算, 得到⼀个 Hash 值。
- 然后 CA 会使⽤⾃⼰的私钥将该 Hash 值加密,⽣成 Certificate Signature,也就是 CA 对证书做了签名。
- 最后将 Certificate Signature 添加在⽂件证书上,形成数字证书。
- 客户端校验服务端的数字证书的过程
- ⾸先客户端会使⽤同样的 Hash 算法获取该证书的 Hash 值 H1。
- 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使⽤ CA 的公钥解密 Certificate Signature 内容,得到⼀个 Hash 值 H2 。
- 最后⽐较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
2.4、SSL与TLS
- SSL:(Secure Socket Layer,安全套接字层),位于可靠的面向连接的网络层协议和应用层协议之间的一种协议层。SSL通过互相认证、使用数字签名确保完整性、使用加密确保私密性,以实现客户端和服务器之间的安全通讯。该协议由两层组成:SSL记录协议和SSL握手协议。
- TLS:(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。该协议由两层组成:TLS记录协议和TLS握手协议。TLS是HTTP与TCP协议之间的一层,通常TLS发生在TCP三次握手之后,此时进行TLS四次握手,然后再进行HTTP通信。
2.5、HTTPS涉及的计算环节
- 非对称密钥交换。比如RSA, Diffie-Hellman, ECDHE.这类算法的主要作用就是根据客户端和服务端不对称的信息,经过高强度的密钥生成算法,生成对称密钥,用于加解密后续应用消息。
- 对称加解密。服务端使用密钥A对响应内容进行加密,客户端使用相同的密钥A对加密内容进行解密,反之亦然。
- 消息一致性验证。每一段加密的内容都会附加一个MAC消息,即消息认证码。简单地说就是对内容进行的安全哈希计算,接收方需要校验MAC码。
- 证书签名校验。这个阶段主要发生在客户端校验服务端证书身份时,需要对证书签名进行校验,确保证书的真实性。
