无论是大厂面试还是小厂面试,无论是社招还是校招,博主做了大量的统计分析,计算机网络中的HTTP协议相关的考点,几乎是必考的,让我们一起来学习这个知识吧。
一、HTTP2新特性
首先,我们要明确HTTP2到底有哪些新特性。博主总结了多篇文章,HTTP2新特性主要围绕着下面六个方面。
- 二进制分帧
- 首部压缩
- 流量控制
- 多路复用
- 请求优先级
- 服务器推送
二进制分帧
在介绍二进制分帧之前,首先介绍下什么是帧,但是介绍帧的时候,又不可避免的要介绍到消息和数据流的概念,为了便于大家的理解,博主还是决定对这些内容分别进行系统的介绍。
帧、消息和数据流的关系
- 帧(frame):可以理解为一个连续的消息流中的一个片段,是最小单位。
- 消息(message):对应于HTTP1中的请求或者响应,包含一条或者多条message。
- 数据流(stream):包含1条或者多条message。
HTTP2突破HTTP1.1协议性能限制的核心
HTTP2所有性能增强的核心就在于应用层和传输层之间增加了一个二进制分帧层。
二进制分帧层原理
二进制分帧层通过将所有传输的信息分割为更小的消息和帧,并采用二进制格式进行编码,其中,HTTP1.1中的首部信息header封装到Headers帧中,而request body则封装到Data帧中。HTTP2的通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流,相应的每个数据流以消息的形式发送,而消息由一个或多个帧组成,这些帧可以乱序发送,然后根据每个帧的首部流标识符重新组装。二进制分帧为HTTP2的其他特性提供了基础。
二进制帧的结构
下图是二进制帧的结构图
HTTP2的二进制帧主要包括头部帧和数据帧,其中头部帧包括3个字节的帧长度,1字节的帧类型和1字节的标志位以及31bit的流标识符,接下来将详细介绍每一部分的作用。
- 帧长度:表示的是数据帧的长度。
- 帧类型:表示这个帧是数据帧还是控制帧。
- 标志位:用于携带简单的控制信息,例如通过标志位来表示流的优先级。
- 流标识符:用来表示这个帧属于哪个流的,接收方可以根据这个信息从乱序的帧里面找到相同流id的帧,从而有序的组装信息。
- 数据帧:存放的时经过HPACK算法压缩后的HTTP头部和数据体。
首部压缩
首部压缩的原理
HTTP2使用HPACK算法压缩请求和响应标头的元数据,这种格式支持通过静态霍夫曼编码对传输的头部字段进行编码,从而减小了传输的大小,同时这种压缩算法要求客户端和服务器同时维护和更新一个首部表,这个首部表能够跟踪和存储之前发送过的键值对,对于相同的数据不再通过每次请求和响应进行发送,假如第一个请求发送了所有的头部字段,第二个请求则只需发送有差异的字段,这样可以减少冗余的数据,降低开销。HPACK主要包含两个压缩模块,索引表和静态霍夫曼编码,其中索引表又包含静态表和动态表。静态表包含61个预定义Header的Key value,传输的时候使用对应的索引Index替换。动态表是一个先进先出的队列,初始的时候是空的,解压header的时候按需添加,每次添加的时候放在队首,移除的时候从队尾开始,动态表的大小不是无限制的。
HPACK算法
HPACK算法主要包括三个组成部分。
- 静态表
- 动态表
- Huffman压缩算法
客户端和服务端都会建立和维护一张字典,主要目的时使用长度较小的索引号表示重复的头部字符串,再用Huffman编码压缩数据,可以达到较高的压缩率。
静态表:HTTP2为出现在头部的字符串和字段建立了一张静态表,它是写入到HTTP2客户端和服务器的代码中的,静态表里共有61组,例如,在静态表中GET方法的索引号是2,POST方法的索引号是3。静态表的索引表示的是头部名,value表示的是头部名对应的内容。
动态表:因为静态表只包含了61中高频出现在头部的字符串,不在静态表范围的头部字符串就需要我们自行构建动态表,这个动态表的索引从62起步,比如第一次发送user-agent,会将这个字符串对应的索引号,字符串和对应的数据经过霍夫曼编码后的二进制值发送给服务端,在第二次发送的时候,就不用重复发送这个字段的数据了,只用发送一个字节的索引号即可,因为双方都可以根据自己的动态表获取到该字段的值。这样避免了大量的冗余数据的传输,节约了带宽。
动态表会无限制扩大吗?答案是否定的,因为动态表越大占用的内存也就越大,是会影响服务器性能的,所以web服务器会提供相应的配置,避免动态表无限增大,达到上限后便会关闭HTTP2连接释放内存。
流量控制
在HTTP2协议中,我们可以在同一个TCP连接中,建立多个数据流,这些数据流之间也是存在相互竞争的,因此也需要对流中的帧进行流量控制,但是只有流量帧受流量控制,而其他类型的帧不受流量控制,HTTP2通过使用WINDOW_UPDATE帧来提供流量控制。
HTTP2协议中的流量控制有以下几个特征:
- 流量控制基于HTTP连接的每一跳进行的,而非端到端的控制。(这里的每一跳指的是HTTP连接中间可能的代理服务器)
- 接收方公布自己打算在每个流以及整个连接上分别接收多少字节,这是一个以信用为基础的方案。
- 流量控制是有方向的,由接收者全面控制,接收方可以为每个流和整个连接设置任意的窗口大小,发送方必须尊重接收方设置的流量控制限制。
- 无论是新流还是整个连接,流量控制窗口的初始值是65535字节。
- HTTP2只定义了WINDOW_UPDATE帧的格式和语义,并没有对通信双方如何实现进行约束。
多路复用
在HTTP1.1中,如果客户端想发送多个并行的请求,必须使用多个TCP连接,而HTTP2的二进制分帧层突破了这一限制,所有的请求和响应都在同一个TCP连接上完成,单个连接可以承载任意数量的双向数据流,数据流以消息的形式发送,消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为可以根据帧首部的流标识符进行重新组装。
上面的特性使得性能有了极大的性能提升,原因如下:
- 因为同一个域名只需要占用一个TCP连接,使用这个连接并行发送多个请求和响应,这样使得整个页面的资源的下载过程只需要一次慢启动,同时也避免了多个TCP连接带来的竞争问题。
- 可以并行交错的发送多个请求或响应,这些请求或响应之间互不影响。
请求优先级
HTTP2中每个流都可以带有一个31bit的优先值,0表示做高优先级,数值越大优先级越低,在一个TCP连接上,可以发送多个请求,并不等于说这些请求对于服务器来说都是一视同仁的,因为客户端对资源的需求不同,比如客户端对css和js的需求远大于对文档内图片的需求,所以每一个流的headers帧中可以带有一个优先级,服务端可以因此适当分配资源,优先发送优先级高的帧。服务端在使用请求优先级的时候要避免带来队头阻塞的问题。
服务器推送
HTTP2改变了传统的请求应答模式,服务器不再完全被动地响应请求,也可以新建流主动向客户端发送消息,比如,浏览器刚请求HTML页面的时候,服务器可能会将主页内容,logo以及样式表都响应到客户端的缓存,当客户端需要这些资源的时候,这些资源已经在缓存中了,这样可以减少等待的延迟,不过只有建立连接后,服务器才可以推送资源,这种机制就是服务器推送。
服务器推送的特点:
- 针对每一个希望发送的资源,服务器会发送一个PUSH_PROMISE帧,当然客户端有权选择拒绝这个资源,通过RST_STREAM帧,这一步的操作先于父响应(index.html),客户端了解到服务器端打算推送哪些资源,就不会为这些资源创建重复的请求,当客户端收到index.html的响应时,script.js和style.css已经存在于缓存中了。
二、HTTP2有什么缺点?
- TCP以及TCP+TLS建立连接的延时,HTTP2使用TCP协议来传输,而如果使用HTTPS还需要使用TLS协议进行安全传输,而使用TLS也需要一个握手的过程,这也会带来一些延时。
- TCP的队头阻塞并没有彻底解决,在HTTP2中,多个请求是在一个TCP管道中的,当HTTP2出现丢包的时候,整个TCP都要开始等待重传,此时会阻塞该TCP连接中的所有请求。此时可能还不如HTTP1.1中的多个TCP连接效率高。队头阻塞分为TCP队头阻塞和HTTP队头阻塞,HTTP2解决的是HTTP队头阻塞,但是TCP的队头阻塞并未解决。因为HTTP是应用层协议,TCP是传输层协议。
- 多路复用导致服务器压力上升,多路复用由于没有限制同时请求数量,有可能出现短时间内请求数爆发的情况,会导致服务器压力上升。
- 多路复用容易超时,大批量的请求同时发送,但是网络的带宽和服务器的资源是有限的,此时可能会出现请求超时的情况。
HTTP2.0多路复用在什么情况下效率不如1.1?
HTTP2.0在丢包的时候效率可能不如1.1,因为在出现丢包的情况下,整个TCP都要开始等待重传,也就导致后面的所有数据都被阻塞了,但是对于HTTP1.1来说,可以开启多个TCP连接,出现这种情况只会影响到其中一个连接,剩余的TCP连接还可以正常传输数据。
二进制分帧的根本目的是什么,只是为了读取速度快吗?
二进制分帧的根本目的是为了更有效的利用底层TCP协议,同时也是HTTP2协议中的其他功能和性能优化的基础。
HTTP2中的长连接相比于http1中手动指定keep-alive的优势、原理
- HTTP1.X中的keep-alive必须按照请求发送的顺序返回响应,但是HTTP2多路复用可以不按顺序进行响应。
- HTTP1.X中的keep-alive单个TCP连接在同一时刻只能处理一个请求,HTTP2单个TCP在同一时刻可以发送多个请求和响应。
三、HTTP3.0
为什么要有HTTP3.0?
之所以要有HTTP3主要原因还在于上文提到的HTTP2存在的问题,这些问题的根源是底层支撑的TCP协议造成的。Google意识到这些问题之后,于是就提出了基于UDP协议的QUIC协议,让HTTP跑在QUIC上,而不是TCP上,这就是HTTP3,HTTP3解决了HTTP2存在的队头阻塞问题。
HTTP3为什么选择UDP?
HTTP3选择UDP主要有以下一些原因:
- 基于TCP开发的设备和协议非常多,兼容起来困难。
- TCP协议栈是Linux内部的重要部分,修改和升级成本很大。
- UDP本身是无连接的、没有建链和拆链成本。
- UDP的数据包无队头阻塞问题。
- UDP改造成本小。
HTTP3新特性
- 多路复用,解决了TCP队头阻塞问题。
HTTP2.0协议的多路复用机制解决了HTTP层的队头阻塞问题,但是在TCP层仍然存在队头阻塞问题,如果基于TCP协议,会出现某个数据包丢失导致整个连接数据被阻塞。QUIC协议是基于UDP协议实现的,在一条链上可以有多个流,流与流之间是互不影响的,一个流的包发生丢包只需这个流的包进行重传,其他流的包不受影响,这样就解决了TCP存在的队头阻塞问题,同时QUIC协议在移动端的表现也比TCP好,因为TCP是基于IP和端口号去识别连接的,这种变化在多变的移动端网络环境下是很脆弱的,QUIC通过Id的方式去识别连接,不管网络环境如何变化,只要ID不变,就能迅速连上。
- 0RTT建链
RTT指的是数据包在网络中一来一回的时间消耗。RTT包括三部分:往返传播时延、网络设备内排队时延、应用程序数据处理时延。
一般来说HTTPS协议建立完整的链接需要TCP握手和TLS我受不,总计至少需要2-3个RTT,普通的HTTP协议也需要至少一个RTT才可以完成握手,然而QUIC协议可以实现在第一个包就包含有效的应用数据,从而实现0RTT,但是这是有前提条件的,对于第一次交互的客户端和服务端0RTT也是做不到的,因为双方需要进行1RTT的密钥交换,首次连接客户端对密钥信息进行了缓存,在缓存有效时间内,再次连接可以跳过这个1RTT,实现0RTT的数据交互。
- 前向纠错机制
QUIC协议的的每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传,向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传,因为数据重传将会消耗更多的时间,假如要发送三个包,协议会计算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包,当非校验包丢失的时候,可以通过另外三个包计算出丢失的数据包的内容,当然这种技术只能使用在丢失一个包的情况,如果出现丢失多个包的情况,就只能使用重传机制了。
- 连接迁移
网络切换几乎无时无刻都在发生。TCP协议使用五元组来表示一条唯一的连接,当我们从4G环境切换到WiFi环境的时候,手机的IP地址会发生变化,此时就必须创建新的TCP连接才能继续传输数据。QUIC协议摒弃了五元组的概念,使用64位随机数作为连接的ID,并使用该ID表示连接,基于QUIC协议,在切换流量和WiFi的时候,不会出现重连的情况,提高了效率。
- 加密认证的报文
TCP协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听,但是QUIC除了个别报文外,所有报文头部都是经过加密认证的。
- 实现了类似TCP的流量控制,传输可靠性的功能。
虽然UDP不提供可靠性的传输,但QUIC在UDP的基础上增加了一层来保证数据可靠性的可靠性传输,它提供了数据包重传,拥塞控制以及其他一些TCP中存在的特性。
四、HTTP.0 HTTP1.1 HTTP2.0的区别
HTTP1.0和HTTP1.1之间的区别
- 缓存处理
在HTTP1.0中主要是用header里面的If-Modified-Since,Expires作为缓存判断的标准,而HTTP1.1则引入了更多的缓存控制策略,例如Etag,If-Unmodified-Since,If-Match,If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用
在HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的某一部分,而服务器却将整个对象传送过来了,并且不支持断点续传功能。HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
- 错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,如409(Conflit)表示请求的资源和资源的当前状态发生冲突,410(Gone)表示服务器上的某个资源被永久的删除。
- Host头处理
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此请求消息中的URL并没有传递主机名Hostname,但是随着虚拟主机的发展,在一台物理服务器上可以存在多个虚拟主机,并且共享一个IP地址,HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误400 Bad Request。
- 长连接
HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
HTTP2.0和HTTP1.1之间的区别
- 新的二进制格式
HTTP1.1的解析是基于文本的,基于文本协议的格式解析存在天然缺陷,二进制则不同,只有0和1的组合,基于这种考虑HTTP2.0的协议解析采用二进制格式,实现方便且健壮。
- 多路复用
关于这部分的介绍请看HTTP2.0新特性关于多路复用的介绍。
- 首部压缩
关于这部分的介绍请看HTTP2.0新特性关于首部压缩的介绍。
- 服务器推送
关于这部分的介绍请看HTTP2.0新特性关于服务器推送的介绍。
五、Keep-Alive机制
说起keep-alive,我们首先要明确的是,有两种keepalive,一种是TCP的keepalive,另一种是HTTP的keep-alive。
TCP的keepalive
TCP的keepalive存在的主要意义是保持客户端和服务端的连接,一方会不定期的发送心跳包给另一方,如果间隔发送几次,对方返回的都是RST,而不是ACK,那么就释放当前的连接,如果TCP层没有keepalive的机制,一旦一方断开连接却没有发送FIN给另外一方,那么另外一方会一直以为这个连接还存在,长时间的话,这对服务器的资源的影响是很大的。
HTTP的keep-alive
HTTP层的keep-alive主要是为了复用TCP连接,HTTP服务的发起方一般都是浏览器,一般先执行完逻辑并传输完数据的一定是服务端,假如没有keep-alive机制的存在,服务端在传输完数据之后会首先断开连接,由于TCP的四次挥手的机制,先发起断开连接的一方会进入TIME_WAIT状态并等待2MSL的时间,客户端的每一次请求服务端都要消耗这个时间,但是服务器的资源是非常有限的,这对服务器端的消耗是巨大的,所以HTTP层的keep-alive是非常重要的。
二者区别
TCP的keepalive是在ESTABLISHED状态,主要是用于检测连接的可用性,而TCP的keep-alive主要是为了进行TCP连接的复用,避免频繁的TCP三次握手和四次挥手的环节。
六、HTTP基本结构
HTTP协议在哪一层?下面那一层是什么协议?
HTTP协议在应用层,如果是TCP/IP四层网络模型的话,下一层是传输层,这一层一般是TCP/UDP协议。
HTTP有哪些请求方法?
HTTP1.0定义了三种请求方法:GET、HEAD、POST方法。 HTTP1.1新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE和CONNECT方法。
- GET:请求指定的页面信息,并返回实体主体。
- HEAD:类似GET请求,只不过返回的响应中没有具体的内容,用于获取报头。
- POST:向指定资源提交数据,例如提交表单。
- PUT:通过该方法客户端可以将指定资源的最新数据传送给服务器取代指定资源的内容。
- DELETE:请求服务器删除指定的资源。
- CONNECT:当浏览器配置为使用代理服务器时才会用到CONNECT方法。
- OPTIONS:用于描述目标资源的通信选项,查看服务器支持哪些请求方法。
- TRACE:沿着到目标资源的路径执行一个消息环回测试,可用于debug测试。
- PATCH:对已知资源进行局部更新。
HTTP有哪些常见的请求头?
下面介绍一些常用的请求头。
- Accept: 浏览器可以接受服务器返回的类型。
- Accept-Encoding:浏览器申明自己能够处理的压缩或编码方法。
- Accept-Language:用于浏览器声明自己接收的语言。
- Connection
- Connection: keep-alive 当一个网页打开完成之后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。即TCP连接的复用。
- Connection:close 代表一个Request完成之后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送请求的时候,需要重新建立TCP连接。
- Host: 发送请求时,该报头域是必需的,主要用于指定被请求资源的主机和端口号。
- Referer:这个字段主要是告诉服务器,该请求是从哪个页面链接过来的。
- User-Agent:告诉服务器,客户端使用的操作系统和浏览器的名称和版本。
- Cache-Control:
- private:告诉服务器响应只能作为私有缓存,不能再用户间共享。
- public:响应可以被缓存并再多用户间共享
- no-cache:使用协商缓存。
- no-store:不缓存。
- cookie:用于存储一些用户信息以便让服务器辨别用户身份,例如cookie中可能会存储用户的id和密码,当用户登录后就会再客户端产生一个cookie来存储相关信息,这样浏览器通过读取cookie信息去服务器上验证并通过后可以认定是否是合法用户。
- Range:用于断点续传,告知服务器自己想要获取对象的哪一部分。
HTTP请求体的内容
HTTP的请求体一般有三种形式,例如:
- application/json
- text/xml
- application/x-www-form-urlencoded
HTTP的报文结构
HTTP的报文结构包括请求报文的报文结构和响应报文的报文结构。
请求报文的报文结构
- 请求行:请求方法 + 请求URL + HTTP版本
- 请求头:字段名和对应的值
- 空行:请求头之后是一个空行,主要是告知服务器下面不在有请求头。
- 请求体:由用户自定义添加,例如post方法的body部分。
响应报文的报文结构
- 状态行: HTTP版本 + 状态码 + 状态描述符(OK)
- 响应头:字段名 + 对应的值
- 空行
- 响应体
什么是HTTP劫持?
当用户的浏览器和目标服务器建立连接通道后,当浏览器发起HTTP请求后,运营商的路由器会首先收到这次HTTP请求,之后运营商路由器的旁路设备会将此TCP连接为HTTP协议,然后抢在网站服务器返回数据之前发送HTTP协议的302状态码进行劫持,浏览器以为是临时重定向,便跳转到目标URL上,旁路设备完成标记后会返回修改后的HTML代码,导致浏览器中被插入了运营商的广告,随后网站服务器的真正数据会被丢弃。
七、HTTP1.0存在的问题
HTTP1.0主要存在以下几个问题:
- 无法复用连接,每次发送请求都需要进行一次TCP连接,而TCP的连接释放过程又是比较增加延时的,这样会使得网络带宽的利用率比较低。
- 存在队头阻塞的问题,一个请求必须在前一个请求响应到达之后才能发送。
- 不支持断点续传,也就是说每次都会传送全部的页面和数据。
八、HTTPS加密原理
为什么要有HTTPS?
之所以要有HTTPS,是因为HTTP协议是一种不安全的传输协议,HTTP在传输数据的过程中,所有的数据都是明文传输,即使在前端通过一些加密算法进行加密后,服务端也是无法直接进行解密的。
对称加密和非对称加密
HTTPS解决数据传输安全问题的方案就是使用加密算法,具体来说是对称加密和非对称加密的混合使用,下面我们先介绍下这两种加密算法的特点。
对称加密
对称加密指的是加密和解密都用的同一个密钥,常用的对称加密算法有DES,AES等。
- 优点:算法公开,计算量小、加密速度快、加密效率高、适合对比较大的数据进行加密。
- 缺点:由于交易双方使用的是相同的密钥,所以无法避免密钥的传输,密钥在传输的过程中可能会被截获,用户每次使用对称加密算法,都需要使用其他人不知道的唯一密钥,这会使得双方所拥有的的钥匙数量急剧增长,密钥管理更加困难。
非对称加密
非对称加密就是加密和解密使用两个不同的密钥:公钥和私钥。其中公钥和私钥是一堆,如果使用公钥对数据进行加密,只有用对应的私钥才能进行解密。如果使用私钥对数据进行加密,那么只有使用对应的公钥才能进行解密。非对称加密算法实现信息交换的基本过程是:客户端拿到服务器的公钥后,会生成一个随机KEY,然后使用公钥把这个KEY进行加密然后发送给服务器,服务器使用私钥将其解密,这样双方都拥有了同一个密钥KEY,然后就可以使用这个KEY进行对称加密交互数据,同时避免了KEY传输被拦截的情况,也就保证了加密数据的安全。
- 优点:算法公开,加密和解密使用的是不同的钥匙,私钥不需要通过网络进行传输,安全性很高。
- 缺点:计算量比较大,加密和解密速度相比对称机密慢很多。
HTTP和HTTPS之间的关系
- HTTPS = HTTP + SSL/TLS
HTTPS的加密流程
HTTPS的整个通信过程可以分为两大阶段,一是证书验证阶段,二是数据传输阶段,其中数据传输阶段又可以分为非对称加密和对称加密两个阶段。
- 客户端请求HTTPS的网址,然后连接到服务器的443端口。(HTTPS默认的端口是443,HTTP默认的端口是80)。
- 采用HTTPS协议的服务器必须要有一套由数字证书认证机构颁发的CA证书,颁发证书的同时会产生一个私钥和公钥,私钥是由服务端保存的,不可泄露,公钥则是附带在证书的信息中,可以公开的。证书本身也带有一个证书电子签名,这个签名是用来验证证书的完整性和真实性,可以防止证书被篡改。
- 服务器响应客户端请求,将证书传递给客户端,证书中包含公钥和大量其他信息,比如证书颁发机构信息、公司信息和证书有效期等,通过chrome浏览器点击地址栏的锁标志可以查看证书的详细信息。
- 客户端解析证书并对其进行验证,如果证书不是可信机构颁发的,或者证书中的域名和实际域名不一致,或者证书过期,就会对访问者显示警告信息,如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥A,然后客户端还会生成一个随机码KEY,并使用公钥A将其加密。
- 客户端把加密后的随机码KEY发送给服务器,作为后面对称加密的密钥。
- 服务器在收到密文后,会通过私钥解析出随机码KEY。
- 服务器使用上述步骤获取到的KEY,对数据进行对称加密并发送给客户端,客户端使用相同的KEY对数据进行解密。
- 然后双方使用对称加密传输完所有数据。
HTTP和HTTPS的区别
- 安全性不同。HTTP明文传输,不对数据进行加密安全性较差,HTTPS的数据传输过程是加密的,安全性较好。
- 是否需要申请CA证书。HTTPS协议需要申请证书,HTTP协议不需要。
- 页面响应速度不同。HTTP页面响应速度比HTTPS快,因为HTTPS多了一层加密层,所以会影响速度。HTTP协议使用TCP三次握手建立连接,客户端和服务器交换需要三个包,而HTTPS除了TCP的三个包之外,还要加上ssl的九个包。
- 端口不同。HTTP默认的是80端口,HTTPS默认的是443端口。
- 消耗服务器资源不同。HTTPS是构建在SSL/TLS之上的HTTP协议,所以更加消耗服务器的资源。
HTTPS的缺点
- HTTPS协议握手阶段比较费时,会使页面的加载时间延长50%,增加10%到20%的耗电。
- SSL证书需要一定的费用,功能越强大的证书费用较高。
- HTTPS需要较高的服务器资源,会导致成本上升。
- HTTPS协议的加密范围比较有限,某些国家如果能够控制CA根证书的情况下,中间人攻击也是可行的。
TLS工作原理及详细握手过程
HTTPS相比于HTTP最大的不同就是多了一层SSL或TLS,SSL和TLS协议可以为通信双方提供识别和认证通道,从而保证了通信的机密性和数据完整性,不过目前SSL逐渐被TLS协议取代,因此下文主要对TLS进行介绍。TLS握手是启动HTTPS通信的过程,类似于TCP建立连接时的三次握手,在TLS握手的过程中,通信双方交换消息以相互验证,相互确认,并确立它们所使用的加密算法以及用于对称加密的密钥,所以TLS握手时HTTPS通信的基础部分。
TLS握手的主要目的
- 协商双方通信所使用的TLS版本(例如TLS1.0还是1.2)。
- 确定双方要使用的密码组合。
- 客户端通过服务器的公钥和数字证书上的数字签名验证服务端的身份。
- 生成会话密钥,该密钥将用于握手结束后的对称加密。
TLS握手的详细过程(重看 RSA 1.2 1.3)
不同的密钥交换算法,TLS的握手过程有一些区别,当前TLS握手有三个版本,分别是RSA版本、TLS1.2和TLS1.3。
下面详细介绍下RSA版的TLS握手。传统的TLS握手基本都是使用RSA算法来实现密钥交换的。,接下来,我们对RSA版的TLS的每一次握手进行介绍。
- 第一次握手:客户端首先会发送一个Client Hello消息,这个消息中包含了客户端使用TLS版本号,支持的密码套件列表,以及客户端生成的随机数,这个随机数会被服务器端保留,是生成对称加密密钥的参数之一。
- 第二次握手:服务端收到客户端的Client Hello消息后,会确认TLS版本号是否支持,然后从客户端支持的密码套件列表中选择一个密码套件,然后生成服务端随机数,然后返回Server Hello消息,消息里面包含了服务器选择的TLS版本号,和服务端随机数,和服务端选择的密码套件,同时服务端还会将自己的数字证书发送给客户端。(客户端和服务端都会各自生成一个随机数,并且会把随机数传递给对方,这两个随机数是作为后续生成会话密钥的条件)
- 第三次握手:客户端验证完服务端的证书后,如果该证书是可信证书的话,客户端会生成一个随机数pre-master(预主密钥),然后用服务器的RSA公钥加密该随机数(RSA公钥是从服务端发过来的数字证书中提取的),然后传递给服务端。服务端收到后,会用RSA私钥进行解密,得到客户端发过来的随机数pre-master,至此,客户端和服务端均拥有了三个随机数,分别是Client Random、Server Random、pre-master,双方会根据这三个随机数,生成会话密钥,它是对称密钥,用于对后续的HTTP请求和响应数据的加密和解密,生成完会话密钥之后,客户端会发送一个密码策略已经改变的报文给服务端,告诉服务端开始使用加密方式发送消息,然后客户端还会发送一个消息把之前所有发送的数据做一个摘要,然后使用会话密钥加密一下,让服务器做个验证,以验证之前的握手信息有没有被中途篡改过。
- 第四次握手:服务器也会进行同样的操作,发送一个密码策略已经改变的报文,然后也会把之前所有发送的数据做一个摘要,然后使用会话密钥加密之后,让客户端做一个验证,如果双方都验证加密和解密没有问题,那么握手正式完成,之后就会使用会话密钥来加解密HTTP请求和响应了。
RSA算法的缺陷
使用RSA密钥协商算法的最大问题是不支持前向保密,一旦服务端的私钥泄露了,过去第三方截获的所有TLS通讯密文都会被破解,于是有了基于ECDHE算法的TLS1.2,下面简要介绍下TLS1.2的握手过程。
- 第一次握手:客户端向服务端发送Client Hello,这个消息包含了客户端支持的TLS版本号,支持的密码套件列表以及客户端生成的随机数。
- 第二次握手:服务端收到后,会立即返回一个服务端随机数,与服务端选择的密码套件和包含公钥的数字证书,然后服务器将利用私钥将客户端随机数、服务端随机数、和服务端DH参数进行签名,生成服务器签名然后发送给客户端,同时发送这个服务端DH参数。
- 第三次握手:浏览器会先验证数字证书和服务器签名,通过后将客户端的DH参数传递给服务器。接着客户端通过ECDHE算法,利用客户端DH参数和服务端DH参数计算出预主密钥,有了预主密钥、客户端随机数和服务端随机数,客户端利用这三个计算出对称加密的主密钥。
- 第四次握手:服务端也使用ECDHE算法生成预主密钥,然后用相同的方法生成主密钥。当双方都验证通过之后,握手正式结束,后面开始正常收发加密的HTTP请求和响应了。
RSA和ECDHE握手过程的区别
- RSA密钥协商算法不支持前向保密,ECDHE密钥协商算法不支持前向保密。
- 使用了RSA密钥协商的算法,TLS完成四次握手之后,才能进行应用数据的传输,而对于ECDHE算法,客户端可以不用等服务端的最后一次TLS握手,就可以提前发出加密的HTTP数据,节省了一个消息的往返时间。
八、综合性面试题
HTTPS为什么既有对称加密也有非对称加密?
对称加密的加解密使用的是用一个密钥,由于交易双方使用的是相同的密钥,无法避免密钥的传输,密钥在传输的过程中可能会被截获,但是对称加密的计算量较小,加密速度快,加密效率高。非对称加密采用的是公私钥的方式,私钥不在网络中传输,但是计算量比较大,效率不高。所以HTTPS利用这两者的优势,将两种方式结合起来,在交换密钥阶段使用非对称加密的方式,之后建立通信后,使用对称加密的方式。
客户端如何验证证书的有效性?
一个数字证书通常包含了公钥、持有者信息、证书认证机构CA的信息、CA对这份文件的数字签名和使用的算法以及证书的有效期。数字证书的作用就是用来认证公钥持有者的身份,以防止第三方进行冒充,这个则行数是由CA证书认证机构签名的,这个CA证书认证机构是网络世界的认证中心,具有极高的可信度,所以由他签发的证书是可靠的。之所以要签名是为例防止中间人对证书进行篡改。
CA签发证书的过程
- 首先CA会把持有者的公钥、用途、颁发者、有效时间等进行一个打包,然后进行Hash计算,得到一个Hash值。
- 然后CA会使用自己的私钥将该Hash值进行加密,生成一个证书签名。
- 将证书签名添加到文件证书上,形成数字证书。
客户端验证服务端数字证书的过程
- 客户端使用相同的哈希算法获取该证书的哈希值。
- 一般情况下,用户的浏览器和操作系统中集成了CA的公钥信息,浏览器收到证书之后可以使用CA的公钥解密数字签名得到另一个哈希值。
- 浏览器比较两个哈希值,如果值相同,则认为这个证书是可信的,反之认定证书不可信。
HTTPS如何防止中间人攻击?
关于HTTPS防止中间人攻击的方法,我们只需要从上文中的客户端如何验证证书的有效性来回答即可。
参考文献
特别感谢以下博主的文章支持!