HTTP详解(笔记)

HTTP综述

HTTP

HTTP协议特点:

1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

HTTP的基础概念与运作机理

首先HTTP协议通常是承载于TCP协议之上的

工作流程

1.首先客户机与服务器需要建立连接。

Connection:keep-alive

建立在TCP断开连接的抉择上,同时如果开启多个连接,对于server端来说没有这么多套接字或者处理不了这么多的业务,就会采用一些连接关闭资源分配策略:(限制单一客户端,减少无事发生的连接)


关于keep-alive

(1)keepAlive可以简单理解为一种状态保持或重用机制,比如当一条连接建立后,我们不想它立刻被关闭,如果实现了KeepAlive机制,就可以通过它来实现连接的保持。

(2)HTTP的KeepAlive在HTTP 1.0版本默认是关闭的,但在HTTP1.1是默认开启的;操作系统里TCP的KeepAlive默认也是关闭,但一般应用都会修改设置来开启。因此网上TCP流量中基于KeepAlive的是主流

(3)HTTP的KeepAlive和TCP的KeepAlive有一定的依赖关系,名称又一样,因此经常被混淆,但其实是不同的东西.

[HTTP 与 TCP 的 KeepAlive 是一个东西吗? - 云+社区 - 腾讯云 (tencent.com)](https://cloud.tencent.com/developer/article/1461199#:~:text=首先介绍一下 HTTP 协议中 KeepAlive 与 TCP 中,KeepAlive 的区别: HTTP 协议 (七层)的 KeepAlive 意图在于连接复用,希望可以短时间内在同一个连接上进行多次请求%2F响应。)

原因:TCP是一种运行机制,HTTP则是因为其通常是短连接,如果有大量请求会照成浪费,于是通过配置keepalive(由服务端决定长短,通常是在几十秒内)

配置:maxKeepAliveRequests一个连接上,最多可以发起多少次请求**keepAliveTimeout:**底层 Socket 连接最多保持多长时间

TCP为什么要做KeepAlive

在TCP中有一个Keep-alive的机制可以检测死连接,TCP会在空闲了一定时间后发送数据给对方:(TCP心跳)这是一种机制

  • 我们都知道TCP的三次握手和四次挥手。当两端通过三次握手建立TCP连接后,就可以传输数据了,数据传输完毕,连接并不会自动关闭,而是一直保持。只有两端分别通过发送各自的FIN报文时,才会关闭自己侧的连接。
  • 这个关闭机制看起来简单明了,但实际网络环境千变万化,衍生出了各种问题。假设因为实现缺陷、突然崩溃、恶意攻击或网络丢包等原因,一方一直没有发送FIN报文,则连接会一直保持并消耗着资源,为了防止这种情况,一般接收方都会主动中断一段时间没有数据传输的TCP连接,比如LVS会默认中断90秒内没有数据传输的TCP连接,F5会中断5分钟内没有数据传输的TCP连接
  • 但有的时候我们的确不希望中断空闲的TCP连接,因为建立一次TCP连接需要经过一到两次的网络交互,且由于TCP的slow start机制,新的TCP连接开始数据传输速度是比较慢的,我们希望通过连接池模式,保持一部分空闲连接,当需要传输数据时,可以从连接池中直接拿一个空闲的TCP连接来全速使用,这样对性能有很大提升
  • 为了支持这种情况,TCP实现了KeepAlive机制。KeepAlive机制并不是TCP规范的一部分,但无论Linux和Windows都实现实现了该机制。TCP实现里KeepAlive默认都是关闭的,且是每个连接单独设置的,而不是全局设置
  • 另外有一个特殊情况就是,当某应用进程关闭后,如果还有该进程相关的TCP连接,一般来说操作系统会自动关闭这些连接

2.建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。

3.服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。

4.客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。

深入理解HTTP协议(转) - 苏勇的blog - BlogJavawireshark抓取实例

HTTP状态码常见的status及其含义
类型触发动作说明
1XXInformational信息性状态码,表示接受的请求正在处理
2XXSuccess成功状态码,表示请求正常处理完毕
3XXRedirection重定向状态码,表示需要客户端需要进行附加操作
4XXClient Error客户端错误状态码,表示服务器无法处理请求
5XXServer Error服务器错误状态码,表示服务器处理请求出错

1.200状态码,请求被正确的处理,且服务器按照请求返回了结果。

2.204NO Content请求对应的响应没有响应体。

3.206Partial Content客户端进行了范围请求

4.301 Movied Permanently:永久性的重定向,请求的资源已经重新分配了新URL。(浏览器命中缓存无法清除的错误,导致永久重定向)

HEAD:必须在响应头部Location字段中指明新的永久性的URI。

GET:除了有Location字段以外,还需要在响应体中附上永久性URI的超链接文本。

POST:客户端在发送POST请求,受到301响应之后,不应该自动跳转URI,应当让用户确认跳转。

5.302 暂时性地跳转,301和302基本相同,但是302搜索引擎在抓取时会导致旧的网址会保留,而301会采用新的重定向代替暂时访问不到的网址(永久性),302容易照成网址劫持(具体)

(35条消息) http状态码301和302详解及区别_LSGOZJ的博客-CSDN博客_状态码301

搞懂 HTTP 重定向 - 如何优雅地使用 301 - 云+社区 - 腾讯云 (tencent.com)

6.303重定向跟302基本相同,但是需要改变原请求方法成为GET方法

7.304该状态码表示客户端发送附带条件请求时,服务器端允许请求访问资源,但未满足条件的情况。If-MatchIf-Modified-SinceIf-None-MatchIf-RangeIf-Unmodified-Since

8.307临时重定向与302相同

9.400 请求报文中存在语法错误,服务器无法理解该需求

10.401该状态码表示发送的请求需要有通过HTTP认证(Basic认证,Digest认证)的认证信息

11.403该状态码表明对请求资源的访问被服务器拒绝了,未获得文件系统的访问权限,访问权限出现某些问题,从未授权的发送源IP地址试图访问等情况都可能发生403响应。

12.404该状态码表明服务器上无法找到指定的资源。通常被用于服务器不想透露拒绝请求的原因,或者没有其他的响应可提供

13.500服务器端执行出错Internal Server Error

14.503该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

常见请求方法

1.GET请求:请求头中的参数以键队值的形式存在在?之后

2.POST请求:常用于构造后的表单发送等情况,可以携带请求体,同时也能携带url参数进行传递

GET与POST的区别

1.GET在浏览器回退时是无害的,而POST会再次提交请求。//url重解析

2.GET产生的URL地址可以被Bookmark,而POST不可以。//标记地址

3.GET请求会被浏览器主动cache,而POST不会,除非手动设置。//get请求是资源请求会被cache捕获

4.GET请求只能进行url编码,而POST支持多种编码方式。

5.GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

6.GET请求在URL中传送的参数是有长度限制的,而POST么有。//参数长度限制

7.对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

8.GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

9.GET参数通过URL传递,POST放在Request body中。//请求体概念

3.PUT请求:一般用于文件的传输Http/1.1的PUT方法不带验证机制,存在安全性问题

4.HEAD请求只是获取报文的首部信息,而不是返回报文的主体,可以减少信息量,同时确保请求的有效性检验。

5.Delete方法,不带认证机制的方法,一般不会开放使用

6.options方法用于查询一般的请求资源都支持使用什么方法

7.TRACE方法协议定义的一种协议调试方法,该方法会使服务器原样返回任意客户端请求的任何内容。

8.CONNECT方法跳板。

常用的http头(消息报头)

HTTP消息报头包括普通报头、请求报头、响应报头、实体报头(4种)

请求头(常用)
协议头说明示例状态
Accept可接受的响应内容类型(Content-Types)。Accept: text/plain */*表示所有请求的处理固定
Accept-Charset可接受的字符集Accept-Charset: utf-8固定
Accept-Encoding可接受的响应内容的编码方式。Accept-Encoding: gzip, deflate固定
Accept-Language可接受的响应内容语言列表。Accept-Language: en-US固定
Accept-Datetime可接受的按照时间来表示的响应内容版本Accept-Datetime: Sat, 26 Dec 2015 17:30:00 GMT临时
Authorization用于表示HTTP协议中需要认证资源的认证信息Authorization: Basic OSdjJGRpbjpvcGVuIANlc2SdDE==固定
Cache-Control用来指定当前的请求/回复中的,是否使用缓存机制。Cache-Control: no-cache固定
Connection客户端(浏览器)想要优先使用的连接类型Connection: keep-alive``Connection: Upgrade固定
Cookie由之前服务器通过Set-Cookie(见下文)设置的一个HTTP协议CookieCookie: $Version=1; Skin=new;固定:标准
Content-Length以8进制表示的请求体的长度Content-Length: 348固定
Content-MD5请求体的内容的二进制 MD5 散列值(数字签名),以 Base64 编码的结果Content-MD5: oD8dH2sgSW50ZWdyaIEd9D==废弃
Content-Type请求体的MIME类型 (用于POST和PUT请求中)Content-Type: application/x-www-form-urlencoded固定
Date发送该消息的日期和时间(以RFC 7231中定义的"HTTP日期"格式来发送)Date: Dec, 26 Dec 2015 17:30:00 GMT固定
Expect表示客户端要求服务器做出特定的行为Expect: 100-continue固定
From发起此请求的用户的邮件地址From: user@itbilu.com固定
Host表示服务器的域名以及服务器所监听的端口号。如果所请求的端口是对应的服务的标准端口(80),则端口号可以省略。Host: www.itbilu.com:80``Host: www.itbilu.com固定
If-Match仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要用于像 PUT 这样的方法中,仅当从用户上次更新某个资源后,该资源未被修改的情况下,才更新该资源。If-Match: “9jd00cdj34pss9ejqiw39d82f20d0ikd”固定
If-Modified-Since允许在对应的资源未被修改的情况下返回304未修改If-Modified-Since: Dec, 26 Dec 2015 17:30:00 GMT固定
If-None-Match允许在对应的内容未被修改的情况下返回304未修改( 304 Not Modified ),参考 超文本传输协议 的实体标记If-None-Match: “9jd00cdj34pss9ejqiw39d82f20d0ikd”固定
If-Range如果该实体未被修改过,则向返回所缺少的那一个或多个部分。否则,返回整个新的实体If-Range: “9jd00cdj34pss9ejqiw39d82f20d0ikd”固定
If-Unmodified-Since仅当该实体自某个特定时间以来未被修改的情况下,才发送回应。If-Unmodified-Since: Dec, 26 Dec 2015 17:30:00 GMT固定
Max-Forwards限制该消息可被代理及网关转发的次数。Max-Forwards: 10固定
Origin发起一个针对跨域资源共享的请求(该请求要求服务器在响应中加入一个Access-Control-Allow-Origin的消息头,表示访问控制所允许的来源)。Origin: http://www.itbilu.com固定: 标准
Pragma与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生。Pragma: no-cache固定
Proxy-Authorization用于向代理进行认证的认证信息。Proxy-Authorization: Basic IOoDZRgDOi0vcGVuIHNlNidJi2==固定
Range表示请求某个实体的一部分,字节偏移以0开始。Range: bytes=500-999固定
Referer表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面。Referer其实是Referrer这个单词,但RFC制作标准时给拼错了,后来也就将错就错使用Referer了。Referer: http://itbilu.com/nodejs固定
TE浏览器预期接受的传输时的编码方式:可使用回应协议头Transfer-Encoding中的值(还可以使用"trailers"表示数据传输时的分块方式)用来表示浏览器希望在最后一个大小为0的块之后还接收到一些额外的字段。TE: trailers,deflate固定
User-Agent浏览器的身份标识字符串User-Agent: Mozilla/……固定
Upgrade要求服务器升级到一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
Via告诉服务器,这个请求是由哪些代理发出的。Via: 1.0 fred, 1.1 itbilu.com.com (Apache/1.1)固定
Warning一个一般性的警告,表示在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定
响应头(常用)
响应头说明示例状态
Access-Control-Allow-Origin指定哪些网站可以跨域源资源共享Access-Control-Allow-Origin: *临时
Accept-Patch指定服务器所支持的文档补丁格式Accept-Patch: text/example;charset=utf-8固定
Accept-Ranges服务器所支持的内容范围Accept-Ranges: bytes固定
Age响应对象在代理缓存中存在的时间,以秒为单位Age: 12固定
Allow对于特定资源的有效动作;Allow: GET, HEAD固定
Cache-Control通知从服务器到客户端内的所有缓存机制,表示它们是否可以缓存这个对象及缓存有效时间。其单位为秒Cache-Control: max-age=3600固定
Connection针对该连接所预期的选项Connection: close固定
Content-Disposition对已知MIME类型资源的描述,浏览器可以根据这个响应头决定是对返回资源的动作,如:将其下载或是打开。Content-Disposition: attachment; filename=“fname.ext”固定
Content-Encoding响应资源所使用的编码类型。Content-Encoding: gzip固定
Content-Language响就内容所使用的语言Content-Language: zh-cn固定
Content-Length响应消息体的长度,用8进制字节表示Content-Length: 348固定
Content-Location所返回的数据的一个候选位置Content-Location: /index.htm固定
Content-MD5响应内容的二进制 MD5 散列值,以 Base64 方式编码Content-MD5: IDK0iSsgSW50ZWd0DiJUi==已淘汰
Content-Range如果是响应部分消息,表示属于完整消息的哪个部分Content-Range: bytes 21010-47021/47022固定
Content-Type当前内容的MIME类型Content-Type: text/html; charset=utf-8固定
Date此条消息被发送时的日期和时间(以RFC 7231中定义的"HTTP日期"格式来表示)Date: Tue, 15 Nov 1994 08:12:31 GMT固定
ETag对于某个资源的某个特定版本的一个标识符,通常是一个 消息散列ETag: “737060cd8c284d8af7ad3082f209582d”固定
Expires指定一个日期/时间,超过该时间则认为此回应已经过期Expires: Thu, 01 Dec 1994 16:00:00 GMT固定: 标准
Last-Modified所请求的对象的最后修改日期(按照 RFC 7231 中定义的“超文本传输协议日期”格式来表示)Last-Modified: Dec, 26 Dec 2015 17:30:00 GMT固定
Link用来表示与另一个资源之间的类型关系,此类型关系是在RFC 5988中定义Link:; rel=“alternate”固定
Location用于在进行重定向,或在创建了某个新资源时使用。Location: http://www.itbilu.com/nodejs固定
P3PP3P策略相关设置P3P: CP="This is not a P3P policy!固定
Pragma与具体的实现相关,这些响应头可能在请求/回应链中的不同时候产生不同的效果Pragma: no-cache固定
Proxy-Authenticate要求在访问代理时提供身份认证信息。Proxy-Authenticate: Basic固定
Public-Key-Pins用于防止中间攻击,声明网站认证中传输层安全协议的证书散列值Public-Key-Pins: max-age=2592000; pin-sha256="……";固定
Refresh用于重定向,或者当一个新的资源被创建时。默认会在5秒后刷新重定向。Refresh: 5; url=http://itbilu.com
Retry-After如果某个实体临时不可用,那么此协议头用于告知客户端稍后重试。其值可以是一个特定的时间段(以秒为单位)或一个超文本传输协议日期。示例1:Retry-After: 120示例2: Retry-After: Dec, 26 Dec 2015 17:30:00 GMT固定
Server服务器的名称Server: nginx/1.6.3固定
Set-Cookie设置HTTP cookieSet-Cookie: UserID=itbilu; Max-Age=3600; Version=1固定: 标准
Status通用网关接口的响应头字段,用来说明当前HTTP连接的响应状态。Status: 200 OK
TrailerTrailer用户说明传输中分块编码的编码信息Trailer: Max-Forwards固定
Transfer-Encoding用表示实体传输给用户的编码形式。包括:chunkedcompressdeflategzipidentityTransfer-Encoding: chunked固定
Upgrade要求客户端升级到另一个高版本协议。Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11固定
Vary告知下游的代理服务器,应当如何对以后的请求协议头进行匹配,以决定是否可使用已缓存的响应内容而不是重新从原服务器请求新的内容。Vary: *固定
Via告知代理服务器的客户端,当前响应是通过什么途径发送的。Via: 1.0 fred, 1.1 itbilu.com (nginx/1.6.3)固定
Warning一般性警告,告知在实体内容体中可能存在错误。Warning: 199 Miscellaneous warning固定
WWW-Authenticate表示在请求获取这个实体时应当使用的认证模式。WWW-Authenticate: Basic固定

了解了关于HTTP的一些基础知识,我们再从它的发展上做更多讲解:

preload

上面这张图展现了HTTP协议在近些年内的进展:

http1.0和1.1区别

1.长连接

可以提高HTTP连接性能的方法:

并行连接

通过多条连接发起并发的HTTP请求。并行连接可以提高复合页面的传输速度,但其连接也有一些缺点

每个事务都会打开/关闭一条新的连接,会耗费时间和带宽。由于TCP慢启动特性存在,每条连接的性能都会有所降低。可打开的并行连接数量实际上是有限的

持久化连接

Web客户端经常会打开到同一个站点的连接。比如,一个Web页面上的大部分内嵌图片通常来自同一个Web站点,而且相当一部分指向其他对象的超链通常都指向同一个站点。初始化了对某服务器HTTP请求的应用程序很可能会不久的将来对那台服务器发起更多的请求,这种性质称为站点局部性。

HTTP1.0通常使用keep-alive方法,通过响应体中的connection方法实现keep-alive首部客户端判断是否关闭连接。

HTTP1.1持久连接 Persistent Connection取代了keep-alive的支持选项,要在事务处理结束之后将连接关闭,HTTP/1.1应用程序必须向报文中显示地添加一个Connection:close首部

管道化优化连接 HTTP流水线技术持久连接且需要一个发送队列:img

Http1.0在长连接时存在的问题关于代理服务器 在处理长连接含keep-alive的报文头域时,如果不支持识别解析报文头(特殊),这样的话在报文传递时候,虽然双方都收到了协议的相关发送响应报文,但是协议有中间服务器的存在所以不会生效。

在keep-alive模式下的响应数据判断:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0zUnDbU3-1665836819382)(C:\Users\86189\Pictures\笔记图\image-20220617155214988.png)]

其中提到的transfer-encoding传输:

1.适用场景是在不知道实现要传输的数据下进行的报文头表示。

2.chunked传输模式,使得消息可以拆解分成小块的形式,逐块进行传输,相对的减轻了消息发送者的缓冲压力。

3.关于每个chunk的组成,chunk分为多个块,结束块标识了长度为0的footer内容,结束块会有拖尾trailer,包含了CRLF作为结束的标记符。

4.transfer-encoding的可选值有:chunked,identity两个,标识自己的余留数据块长度,发送结尾报文。

5.当是identity时会进行顺序流发送,直到服务端关闭连接时候才算结束。

2.HOST域

      HTTP1.1在Request消息头里头多了一个Host域,而且是必传的,HTTP1.0则没有这个域。
      在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发 展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
      HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。此外,服务器应该接受以绝对路径标记的资源请求。

这是关于host域的解释,总结来看就是经过一些虚拟地址技术的发展和服务器的进步,使得ip不再唯一绑定服务器,需要携带更多的信息用于标识和规范使用,同时host域可以为空但是不能没有。

3.带宽优化

这点优化的原因是,1.0中没有断点续传的功能,在下载中断时会出现问题,而且也没有请求区间段服务器资源的能力。(多次请求的带宽)

解决方法就是在请求头中标识引入了range的头域,它支持请求资源的某个部分,在响应消息中Content-Range头域声明了返回的这部分对象的偏移值和长度。(响应码为206,防止cache认为其为完整对象)

(请求报文拒收的消耗)HTTP/1.1加入了一个新的状态码100,户端事先发送一个只带头域的请求,如果服务器因为权限拒绝了请求,就回送响应码401(Unauthorized);如果服务器接收此请求就回送响应码100,客户端就可以继续发送带实体的完整请求了。(这一点是减少携带大量数据的报文被抛弃)

4.Request method&&Status code

这点的优化是细化了更多的方法和状态码,协助服务器拓展业务,或者为报文的扩展头做标识。

5.cache缓存上的优化

1.在1.0中关于此的头域有:

Expires:浏览器会在指定过期时间内使用本地缓存。

Last-Modified:请求对象最后一次的修改时间 (服务端修改时间)

Date:生成消息的具体时间和日期

If-Modified-Since:客户端存取的该资源最后一次修改的时间

Pragma:no-cache:客户端使用该头域说明请求资源不能从cache中获取,而必须回源获取。

2.1.1中优化缓存扩展的特性有:

对于超过Expire的缓存,可以选择性与源服务器重新激活。

新增了Cache-Control的头域,它支持一个可扩展的指 令子集。 请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if- cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must- revalidate、proxy-revalidate、max-age。

关于Vary头域,标识在磁盘中存储的缓存(存在的原因是因为,同一URL下可能会存在不同的响应文档,也就是内容协商的原理),协商字段一般是服务端判断客户端需求资源的标准(比如语言是什么);

(引入运用;也就是在客户端环境下判断类似语言加入到请求头中进行报文的同url语言鉴定分类返回报文)

于是可以引入Accept字段:(它是内容协商的专用字段)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BA6VsCzS-1665836819383)(C:\Users\86189\Pictures\笔记图\image-20220617163252165.png)]

本地存储命中与信息安全的问题:vary可以防止错误文档的返回

在了解到了Http1.1相对1.0做出的优化后,我们再来看2.0又在1.0基础上实现哪些新技术的配合或者限制。

http1.x 和http2.x区别

http2.x设计用来解决1.0的一些问题:

1.0的局限有哪些呢:1.性能低于带宽的使用率(严重消耗带宽)2.资源缓存有局限(cache的协助)

Http2.x设计实现了一些新的功能:

1.Multiplexing and Concurrency:多路复用与并发:

问题引入:在1.X中,同一时间和同一域名下的请求会有一定的数量限制,如果超过了链接上限,则会受到浏览器限制

2.x中的解决方法:减少建立连接的次数和个数,利用同一个TCP链接发松多个资源(TCP同时也是慢启动的滑动窗口 所以过程中通用可以深度利用TCP协议的特点)

并发的实现需要靠二进制分帧实现数据的乱序发送:二进制分帧在应用层和传输层之间实现,

preload

在BinaryFraming中,会将Http Header以及Http Request Data进行二进制编码,将数据放入Binary Framing这一层中。

然后HTTP2会把数据分割成多个二进制帧,并且为其编号来进行区分不同的请求。(帧中包含了length、type、flags、stream identifier、frame playload等多个字段)

1.每一个请求的帧是串行的。

2.不同请求的帧是并行发送的。

2.Stream Dependencies:流依赖(流控策略)

关于流(stream)(一次完整的请求响应实现)

存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数 ID。 HTTP/2 长连接中的数据包是不按请求-响应顺序发送的,一个完整的请求或响应(称一个数据流 stream,每个数据流都有一个独一无二的编号)可能会分成非连续多次发送。它具有如下几个特点:

双向性:同一个流内,可同时发送和接受数据。//双工

有序性:流中被传输的数据就是二进制帧 。帧在流上的被发送与被接收都是按照顺序进行的

并行性:流中的 二进制帧 都是被并行传输的,无需按顺序等待

流的创建:流可以被客户端或服务器单方面建立, 使用或共享

流的关闭:流也可以被任意一方关闭

HEADERS 帧在 DATA 帧前面

流的 ID 都是奇数,说明是由客户端发起的,这是标准规定的,那么服务端发起的就是偶数了

3.Header Compression:http头部的压缩

img

http2.下使用不同的方式来压缩头部来减少报文的大小。(HPACK)

固定替换(Indexs Table索引表):可以通过静态索引表的的方式来把固定的头部报文替换成静态表中的key值,对于不固定的动态表,更新动态维护一张动态表。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y037LZcN-1665836819384)(C:\Users\86189\Pictures\笔记图\image-20220617173406820.png)]

压缩编码:通过Haffuman等压缩编码方法实现报文头部的压缩

具体的替换过程:

HTTP/2.0 Header Compression 头部压缩(下) - 掘金 (juejin.cn)

4.Server Push:服务端推送

这个功能通常被称作“缓存推送”。主要的思想是:当一个客户端请求资源X,而服务器知道它很可能也需要资源Z的情况下,服务器可以在客户端发送请求前,主动将资源Z推送给客户端。

5.关于请求发送的进化

(1)多个TCP链接的请求响应形式 (2)keep-alive不关闭Tcp链接,通过多种判断方式终结链接(存在串行阻塞和同域并行请求限制带来的阻塞)(3)管线化可以克服同域并行请求限制带来的阻塞,可以按照顺序响应并行的请求(4)多路复用可以进行乱序发送和接收解决了并行请求的阻塞问题。

什么是粘包问题,如何解决?

在socket网络编程中,都是端到端通信,由客户端端口+服务端端口+客户端IP+服务端IP+传输协议组成的五元组可以明确的标识一条连接。在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机制来分辨这些数据。

Nagle算法合并了一些本不应该在一起的分组的包:

为什么这些包会出现呢:一个就是发送包的问题,也就是上面介绍的,一个是接收端的问题,粘包无法及时拆解就会导致应用读取到粘包,造成信息混乱。

解决方法

1.通过关闭发送方默认的nagle算法解决,配置TCP_NODELAY选项,但是可能会增大传输消耗。

2.接收方需要提交应用层处理粘包。

3.应用层在从接收缓存中读取分组时,通过不同方法解析出不同的包文(发送加上长度限制和开始结束符)。

了解了Http的一些基础和它的进步更新,我们可以深究它协助浏览器和服务端进行的缓存机制。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMp3QSN4-1665836819384)(https://upload-images.jianshu.io/upload_images/4845448-39248bf4a3b45c3e?imageMogr2/auto-orient/strip|imageView2/2/format/webp)]

HTTP缓存

本质是通过复用以前的资源,可以显著提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP 缓存,变得更加响应性。

http缓存有几种?

首先http缓存被分为私有和共享缓存两种:需要设定缓存权限

私有缓存:用于单用户,在浏览器中设置,支持用户的导航等重复操作和内容离线浏览的实现。

代理缓存:可以被多个用户共享的代理服务命中资源缓存减少网络带宽和出口负载,但是需要代理服务器提供存储。


如果根据是否需要重新向服务器发起请求来分类,可分为(强制缓存,协商缓存)优先级最高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存。

强缓存:通过http头中的Expires和Cache-Control两个字段进行控制。在强缓存中,如果通过两报文头发现目标资源命中,则不与服务端发生通信,返回200状态码。

1:在1.0时,通常采用服务器响应体中的expires头比较本地和服务器的时间戳来判断命中缓存,所以精度不高,后多采用缓存控制头cache实现,

Expire:响应体中的过期时间,命中之后不发送Http请求。

2:cache-control的具体值在下面有解释,HTTP响应报文中同时有Cache-Control和Expires两个字段时,Cache-Control优先级较高,直接根据Cache-Control的值进行缓存。

缓存控制( Cache-Control )

HTTP/1.1定义的 Cache-Control 头用来区分对缓存机制的支持情况,请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。

关于缓存控制头的值:(包含了请求头和响应头,区别这里未区分)

1.no-store:缓存中不得存储任何关于客户端请求和服务端响应的内容

2.no-cache:有请求发出时,缓存会将此请求发到服务器,服务器端会验证请求中所描述的缓存是否过期

3.private(私有缓存):而 “private” 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。

4.public(公有缓存):指令表示该响应可以被任何中间人(译者注:比如中间代理、CDN 等)缓存。

5.max-age:过期机制表示资源能够被缓存(保持新鲜)的最大时间

6.must-revalidate:验证状态的方式,当使用了 “must-revalidate” 指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。

7.s-maxage=:覆盖max-age或者Expires头。如果s-maxage未过期,则向代理服务器请求其缓存内容。(代理中生效)

新鲜度:服务器和客户端约定的新鲜过期时间,并且陈旧的资源(缓存副本)是不会直接被清除或忽略的,所以请求检验到陈旧资源时,缓存会先将此请求附加一个 If-None-Match 头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了 304 (Not Modified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的。


协商缓存:浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。(需要验证)如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是 304。

1.Last-Modified:资源最后的修改时间,如果响应头中携带有此字段 下一次发送时会发送携带If-modified-since(还有unmodified)的请求头,该请求头标识缓存中资源最后的修改时间,如果服务端收到请求发现其中含有mdf字段,没有过期会收到304响应,从缓存中读取,被修改了就会返回200的状态码。

但是使用Last-Modified是有一定缺陷的。在介绍Etag时我们会了解到。

ETags:缓存内容计算 (根据实体内容生成的一段hash字符串,标识资源的状态)

If-None-Match和If-Match是对应Etag的请求,由客户端计算发送,服务端计算返回判断Etag值是否变化。

(Etag会因为服务器区别而产生误判,但是Etag可以解决Last-mdf不能解决的一些问题):什么时候使用Etag?

1.文件周期性更新:内容不改变只修改时间下的缓存命中

2.文件修改频繁但是希望能被重请求(last精度不足)

3.服务器不能精确捕获最后修改时间

http缓存的目标

常见的缓存只能够存储GET响应:(例如以下几点)

1.一个检索GET请求的成功响应(状态码为200)

2.一个例如HTML 文档,图片,或者文件的响应

3.永久重定向的响应(301状态码)

4.错误响应缓存404的一个页面

5.不完全响应(报文头)不会改变的局部信息

6.匹配到作为一个已被定义的 cache 键名的响应。

关于Last-Modified,Etag,Expire

通常 Last-Modified,Etag,Expire 是一起混合使用的,Last-Modified,Etag,Expires 三个同时使用时。先判断 Expire ,然后发送 Http 请求,服务器先判断 last-modified ,再判断 Etag ,必须都没有过期,才能返回 304 响应。

http 缓存策略以及如何设置一个可靠的缓存规则

参考【前端工程师面试宝典】学习说明_互联网校招面试真题面经汇总_牛客网 (nowcoder.com)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enuUAiK2-1665836819385)(https://uploadfiles.nowcoder.com/images/20220301/4107856_1646127327951/FAA50E4B64035E031660B7B26EB16978)]

  • 强缓存
    • 强缓存命中则直接读取浏览器本地的资源,在network中显示的是from memory或者from disk
    • 控制强制缓存的字段有:Cache-Control(http1.1)和Expires(http1.0)
    • Cache-control是一个相对时间,用以表达自上次请求正确的资源之后的多少秒的时间段内缓存有效。
    • Expires是一个绝对时间。用以表达在这个时间点之前发起请求可以直接从浏览器中读取数据,而无需发起请求
    • Cache-Control的优先级比Expires的优先级高。前者的出现是为了解决Expires在浏览器时间被手动更改导致缓存判断错误的问题。
      如果同时存在则使用Cache-control。
  • 强缓存-expires
    • 该字段是服务器响应消息头字段,告诉浏览器在过期时间之前可以直接从浏览器缓存中存取数据。
    • Expires 是 HTTP 1.0 的字段,表示缓存到期时间,是一个绝对的时间 (当前时间+缓存时间)。在响应消息头中,设置这个字段之后,就可以告诉浏览器,在未过期之前不需要再次请求。
    • 由于是绝对时间,用户可能会将客户端本地的时间进行修改,而导致浏览器判断缓存失效,重新请求该资源。此外,即使不考虑修改,时差或者误差等因素也可能造成客户端与服务端的时间不一致,致使缓存失效。
    • 优势特点
      • HTTP 1.0 产物,可以在HTTP 1.0和1.1中使用,简单易用。
      • 以时刻标识失效时间。
    • 劣势问题
      • 时间是由服务器发送的(UTC),如果服务器时间和客户端时间存在不一致,可能会出现问题。
      • 存在版本问题,到期之前的修改客户端是不可知的。
  • 强缓存-cache-control
    • 已知Expires的缺点之后,在HTTP/1.1中,增加了一个字段Cache-control,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求。
    • 这两者的区别就是前者是绝对时间,而后者是相对时间。下面列举一些Cache-control字段常用的值:(完整的列表可以查看MDN)
      • max-age:即最大有效时间。
      • must-revalidate:如果超过了max-age的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
      • no-cache:不使用强缓存,需要与服务器验证缓存是否新鲜。
      • no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,包括强制和对比。
      • public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
      • private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。
    • Cache-control 的优先级高于 Expires,为了兼容 HTTP/1.0 和 HTTP/1.1,实际项目中两个字段都可以设置。
    • 该字段可以在请求头或者响应头设置,可组合使用多种指令:
      • 可缓存性
        • public:浏览器和缓存服务器都可以缓存页面信息
        • private:default,代理服务器不可缓存,只能被单个用户缓存
        • no-cache:浏览器器和服务器都不应该缓存页面信息,但仍可缓存,只是在缓存前需要向服务器确认资源是否被更改。可配合private,
          过期时间设置为过去时间。
        • only-if-cache:客户端只接受已缓存的响应
      • 到期
        • max-age=:缓存存储的最大周期,超过这个周期被认为过期。
        • s-maxage=:设置共享缓存,比如can。会覆盖max-age和expires。
        • max-stale[=]:客户端愿意接收一个已经过期的资源
        • min-fresh=:客户端希望在指定的时间内获取最新的响应
        • stale-while-revalidate=:客户端愿意接收陈旧的响应,并且在后台一部检查新的响应。时间代表客户端愿意接收陈旧响应
          的时间长度。
        • stale-if-error=:如新的检测失败,客户端则愿意接收陈旧的响应,时间代表等待时间。
      • 重新验证和重新加载
        • must-revalidate:如页面过期,则去服务器进行获取。
        • proxy-revalidate:用于共享缓存。
        • immutable:响应正文不随时间改变。
      • 其他
        • no-store:绝对禁止缓存
        • no-transform:不得对资源进行转换和转变。例如,不得对图像格式进行转换。
    • 优势特点
      • HTTP 1.1 产物,以时间间隔标识失效时间,解决了Expires服务器和客户端相对时间的问题。
      • 比Expires多了很多选项设置。
    • 劣势问题
      • 存在版本问题,到期之前的修改客户端是不可知的。
  • 协商缓存
    • 协商缓存的状态码由服务器决策返回200或者304
    • 当浏览器的强缓存失效的时候或者请求头中设置了不走强缓存,并且在请求头中设置了If-Modified-Since 或者 If-None-Match 的时候,会将这两个属性值到服务端去验证是否命中协商缓存,如果命中了协商缓存,会返回 304 状态,加载浏览器缓存,并且响应头会设置 Last-Modified 或者 ETag 属性。
    • 对比缓存在请求数上和没有缓存是一致的,但如果是 304 的话,返回的仅仅是一个状态码而已,并没有实际的文件内容,因此 在响应体体积上的节省是它的优化点。
    • 协商缓存有 2 组字段(不是两个),控制协商缓存的字段有:Last-Modified/If-Modified-since(http1.0)和Etag/If-None-match(http1.1)
    • Last-Modified/If-Modified-since表示的是服务器的资源最后一次修改的时间;Etag/If-None-match表示的是服务器资源的唯一标
      识,只要资源变化,Etag就会重新生成。
    • Etag/If-None-match的优先级比Last-Modified/If-Modified-since高。
  • 协商缓存-协商缓存-Last-Modified/If-Modified-since
    • 服务器通过Last-Modified字段告知客户端,资源最后一次被修改的时间,例如Last-Modified: Mon, 10 Nov 2018 09:10:11 GMT
    • 浏览器将这个值和内容一起记录在缓存数据库中。
    • 下一次请求相同资源时时,浏览器从自己的缓存中找出“不确定是否过期的”缓存。因此在请求头中将上次的Last-Modified的值写入到请求头的If-Modified-Since字段
    • 服务器会将If-Modified-Since的值与Last-Modified字段进行对比。如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据。
    • 优势特点
      • 不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200以及资源内容。
    • 劣势问题
      • 只要资源修改,无论内容是否发生实质性的变化,都会将该资源返回客户端。例如周期性重写,这种情况下该资源包含的数据实际上一样的。
      • 以时刻作为标识,无法识别一秒内进行多次修改的情况。 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。
      • 某些服务器不能精确的得到文件的最后修改时间。
      • 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。
  • 协商缓存-Etag/If-None-match
    • 为了解决上述问题,出现了一组新的字段Etag和If-None-Match
    • Etag存储的是文件的特殊标识(一般都是 hash 生成的),服务器存储着文件的Etag字段。之后的流程和Last-Modified一致,只是Last-Modified字段和它所表示的更新时间改变成了Etag字段和它所表示的文件 hash,把If-Modified-Since变成了If-None-Match。服务器同样进行比较,命中返回 304, 不命中返回新资源和 200。
    • 浏览器在发起请求时,服务器返回在Response header中返回请求资源的唯一标识。在下一次请求时,会将上一次返回的Etag值赋值给If-No-Matched并添加在Request Header中。服务器将浏览器传来的if-no-matched跟自己的本地的资源的ETag做对比,如果匹配,则返回304通知浏览器读取本地缓存,否则返回200和更新后的资源。
    • Etag 的优先级高于 Last-Modified
    • 优势特点
      • 可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。
      • 不存在版本问题,每次请求都回去服务器进行校验。
    • 劣势问题
      • 计算ETag值需要性能损耗。
      • 分布式服务器存储的情况下,计算ETag的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时现ETag不匹配的情况。

如何制定一个可靠的缓存策略:

参考:一文彻底掌握HTTP缓存 - 知乎 (zhihu.com)

preview

  • 如果资源不可复用,直接为Cache-Control设置no-store,拒绝一切形式的缓存;
  • 如果资源可复用,考虑是否每次都需要向服务器进行缓存确认,如果是,设置Cache-Control的值为no-cache;
  • 如果不需要每次都向服务器确认,考虑资源是否可以被代理服务器缓存,根据其结果决定是设置为private还是public;
  • 接下来考虑资源的过期时间,设置对应的max-age;
  • 最后,配置协商缓存需要用到的Etag、Last-Modified等参数。

介绍完了HTTP,我们来介绍如何保证它的传输安全,也就是https协议。

HTTP与HTTPS的区别:

HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。

HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

通过上述的简单概念我们可以先引入关于HTTPS的学习

HTTPS

HTTPS为什么会存在:首先数据的传输对于HTTP来讲都是明文进行的,没有安全性。

要保证传递过程中的安全性,就要实现传递过程中的加密算法。下面介绍加密算法的一些思想

非对称加密和对称加密
对称加密:

加密与解密使用同一个密匙:

优点:算法公开、计算量小、加密速度快、加密效率高,适合加密比较大的数据。

缺点:密匙管理很难,单一用户需要采用不同的密匙,密匙也会在初始化时候进行传输,有暴露的风险。

非对称的加密

加密和解密使用不同的密钥:公钥和私钥进行,公钥和私钥加密的信息,只有用对方才能解密。在传递时,服务器暴露公钥,解密的私钥不进行传播。

优点:算法公开,加密和解密使用不同的钥匙,私钥不需要通过网络进行传输,安全性很高。

缺点:计算量比较大,加密和解密速度相比对称加密慢很多。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HV4dGKUd-1665836819386)(https://segmentfault.com/img/bVbClUi/view)]

中和二者优点的方式

采用公钥发送初始化,在客户端生成随机码,利用随机码做为对称加密的key值进行信息交流,中间过程中截断的数据都是做了加密处理,且综合了二者的优点。

介绍完加密算法后我们便知道,** HTTPS = HTTP + SSL / TLS**,于是我们便可以深入研究HTTPS的原理,以及SSL/TLS的原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AO5JWQ50-1665836819386)(https://segmentfault.com/img/bVbClUl/view)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4P1X7s3-1665836819386)(C:\Users\86189\Pictures\笔记图\image-20220606125650340.png)]

HTTPS的通信过程深入

1.证书验证:

客户端对HTTPS网络地址请求,连接到服务端的443端口(HTTOS的默认端口),HTTPS协议需要由一套固定的数字CA(Certification Authority)证书,颁发证书的同时会产生一个私钥和公钥。

私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被篡改。

客户端对服务端发来的证书进行校验,提取出有效的信息。

2.数据传输:

接到服务器传递的公钥后,客户端产生一个随机key,采用公钥对其加密,经过第二轮协商,让服务器能用私钥解析这个随机key,并用该key值进行非对称加密。

HTTP一般在80端口 HTTPS一般工作在443端口

简单了解了HTTPS的工作机理后,我们来做一个深入化的了解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lXpadncm-1665836819387)(https://segmentfault.com/img/bVbClUj)]

上图我们可以观测得到HTTPS是假设在安全层SSL和TLS上的HTTP报文

所以SSL和TLS是什么呢?有什么运作机理

SSL以及TLS

SSL (Secure Sockets Layer 安全套接层)或 TLS (Transport Layer Security 安全传输层协议),SSL 已经逐渐被 TLS 取代,TLS通过握手启动HTTPS通信,通信双方在握手过程中交换信息相互验证,确认它们使用的加密算法和会话密钥。

TLS握手详细过程
  • 商定双方通信所使用的的 TLS 版本 (例如 TLS1.0, 1.2, 1.3等等);
  • 确定双方所要使用的密码组合;
  • 客户端通过服务器的公钥和数字证书上的数字签名验证服务端的身份;
  • 生成会话密钥,该密钥将用于握手结束后的对称加密。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NVb2HdcT-1665836819387)(https://segmentfault.com/img/bVbCCMD)]

步骤解析:

1.**"client hello"消息:**客户端发起"client hello"消息向服务器发起握手请求,该消息包含了客户端所支持的 TLS 版本和密码组合以供服务器进行选择,还有一个"client random"随机字符串。

2."server hello"消息:服务器发送"server hello"消息对客户端进行回应,该消息包含了数字证书,服务器选择的密码组合和"server random"随机字符串。

3.验证,客户端验证服务器证书,确定证书有效性鉴定合法身份

  1. 检查数字签名
  2. 验证证书链
  3. 检查证书的有效期
  4. 检查证书的撤回状态 (撤回代表证书已失效)

4.**“premaster secret"字符串:**客户端向服务器发送另一个随机字符串"premaster secret (预主密钥)”,这个字符串是经过服务器的公钥加密过的,只有对应的私钥才能解密。

5.生成共享密钥:客户端和服务器均使用 client random,server random 和 premaster secret,并通过相同的算法生成相同的共享密钥 KEY

6.服务端和客户端就绪:客户端发送经过共享密钥 KEY加密过的"finished"信号,服务器发送经过共享密钥 KEY加密过的"finished"信号。

7.**达成安全通信:**握手完成,双方使用对称加密进行安全通信。

在上述过程中,有几点是用来确认身份的操作和实体。

证书相关

例如数字证书是由唯一序列号,统一机构颁发的网络验证机制,公钥和私钥可以保证信息发送的安全,但是在协议初始化的报文发送中,也可能会被劫持,利用虚构证书和公钥进行欺骗,所以通过数字签名(文章摘要或段信息hash加密产生)比对运算结果,判断是否数字证书被篡改。

还有证书链的机制:证书路径,是用于认证实体合法身份的证书列表,证书链从根证书开始,并且证书链中的每一级证书所标识的实体都要为其下一级证书签名,而根证书自身则由证书颁发机构签名。客户端在验证证书链时,必须对链中所有证书的数字签名进行验证,直到达到根证书为止。

既然介绍了TLS的相关运作机理,我们可以顺便了解一下SSL以及两者的区别

参考:(36条消息) SSL工作原理概述_田老顺的博客-CSDN博客_ssl工作原理

建议直接看原博文

SSL工作分层结构和握手过程

img

  1. 上层为SSL握手协议(SSL handshake protocol)、SSLpassword变化协议(SSL change cipher spec protocol)和SSL警告协议(SSL alert protocol)
  2. 底层为SSL记录协议(SSL record protocol)

1.SSL握手协议:是SSL协议很重要的组成部分。用来协商通信过程中使用的加密套件(加密算法、密钥交换算法和MAC算法等)、在server和client之间安全地交换密钥、实现server和client的身份验证。//协商

2.SSLpassword变化协议:client和server端通过password变化协议通知对端。随后的报文都将使用新协商的加密套件和密钥进行保护和传输。

3.SSL警告协议:用来向通信对端报告告警信息,消息中包括告警的严重级别和描写叙述。

4.SSL记录协议:主要负责对上层的数据(SSL握手协议、SSLpassword变化协议、SSL警告协议和应用层协议报文)进行分块、计算并加入MAC值、加密。并把处理后的记录块传输给对端。

SSL的握手过程

过程中产生或传递的:会话参数,会话ID,证书,加密套件(密钥交换算法、数据加密算法和MAC算法等)和主密钥

SSL的握手过程一般分为三种:

  • 仅仅验证server的SSL握手过程
  • 验证server和client的SSL握手过程
  • 恢复原有会话的SSL握手过程

仅验证server的SSL握手过程

仅验证server

1.Client Hello消息将它支持的SSL版本号、加密算法、密钥交换算法、MAC算法等信息发送给SSLserver。//协商

2.确定本次通信采用的SSL版本号和加密套件,并通过Server Hello消息通知给SSLclient。(假设SSLserver同意SSLclient在以后的通信中重用本次会话,则SSLserver会为本次会话分配会话ID。并通过Server Hello消息发送给SSLclient–》这一点就是重用的基础)

3.server发送公钥证书和第2点协商结果。

4.协商结束Server Hello Done消息,进行密钥交换

5.SSLclient验证SSLserver的证书合法后,利用证书中的公钥加密SSLclient随机生成的premaster secret,并通过Client Key Exchange消息发送给SSLserver。//发送premas

6.SSLclient发送Change Cipher Spec消息,通知SSLserver允许报文将采用协商好的密钥和加密套件进行加密和MAC计算。//切换协商态

7.SSLclient计算已交互的握手消息(除Change Cipher Spec消息外全部已交互的消息)的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并加入MAC值、加密等),并通过Finished消息发送给SSLserver//发送finish态并且发送校验

8.相同地。SSLserver发送Change Cipher Spec消息,通知SSLclient允许报文将采用协商好的密钥和加密套件进行加密和MAC计算。

9.SSLserver计算已交互的握手消息的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并加入MAC值、加密等),并通过Finished消息发送给SSLclient。

10.SSLclient利用相同的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,假设二者相同。且MAC值验证成功。则证明密钥和加密套件协商成功。

验证server和client的SSL握手过程

img

在原有单边验证的基础上

1.SSLserver发送Certificate Request消息。请求SSLclient将其证书发送给SSLserver。//多了一条证书请求

2.SSLclient通过Certificate消息将携带自己公钥的证书发送给SSLserver。SSLserver验证该证书的合法性。//回传证书

3.SSLclient计算已交互的握手消息、主密钥的Hash值。利用自己的私钥对其进行加密,并通过Certificate Verify消息发送给SSLserver。

4.SSLserver计算已交互的握手消息、主密钥的Hash值。利用SSLclient证书中的公钥解密Certificate Verify消息,并将解密结果与计算出的Hash值比较。假设二者同样,则SSLclient身份验证成功。(客户端证明证书,用私钥签名一段数据给服务器验证)

//简单来讲只是多了一个服务端请求签验,双边证书和公私钥加密的过程,同时可以看出SSLclient的身份验证是可选的,由SSLserver决定是否验证SSLclient的身份

SSL 连接断开后如何恢复?

Session ID:会话编号

Session Ticket:包含了本次会话的信息,比如对话密钥和加密方法等

回复原有的会话的SSL握手过程

img

因为协商会话参数、建立会话的过程中。须要使用非对称密钥算法来加密密钥、验证通信对端的身份。计算量较大,占用了大量的系统资源。所以构建出了这个握手策略

1.SSLclient发送Client Hello消息,消息中的会话ID设置为计划重用的会话的ID。

2.SSLserver假设同意重用该会话,则通过在Server Hello消息中设置同样的会话ID来应答。这样,SSLclient和SSLserver就能够利用原有会话的密钥和加密套件。不必又一次协商。

3.SSLclient发送Change Cipher Spec消息,通知SSLserver报文将采用原有会话的密钥和加密套件进行加密和MAC计算。

4.SSLclient计算已交互的握手消息的Hash值,利用原有会话的密钥和加密套件处理Hash值,并通过Finished消息发送给SSLserver,以便SSLserver推断密钥和加密套件是否正确。

5.相同地。SSLserver发送Change Cipher Spec消息,通知SSLclient报文将采用原有会话的密钥和加密套件进行加密和MAC计算。

6.SSLserver计算已交互的握手消息的Hash值,利用原有会话的密钥和加密套件处理Hash值,并通过Finished消息发送给SSLclient。以便SSLclient推断密钥和加密套件是否正确。

总结以上两者

关于ChangeCipherSpec:它是一个独立协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。

关于Certificate Verify:是certificate证书的签名验证。

关于key exchange:客生成用于创建用于对称加密的密钥的信息

几个secret

Secret Keys

PreMaster secret:是在客户端使用RSA或者Diffie-Hellman等加密算法生成的。它将用来跟服务端和客户端在Hello阶段产生的随机数结合在一起生成 Master Secret。(服务和客户端产生随机)

结构:PreMaster secret前两个字节是TLS的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在Client Hello阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。

Master secret

上面已经提到,由于服务端和客户端都有一份相同的PreMaster secret和随机数,这个随机数将作为后面产生Master secret的种子,结合PreMaster secret,客户端和服务端将计算出同样的Master secret。

MAC:MAC(Message Authentication Code),是一个数字签名,用来验证数据的完整性,可以检测到数据是否被串改

参考:SSL/TLS原理详解 - SegmentFault 思否

证书在上述的过程中十分重要,如果不添加证书,则会造成一些安全问题,比如:

HTTPS 中间人攻击

中间人攻击过程如下:

  1. 服务器向客户端发送公钥;
  2. 攻击者截获公钥,保留在自己手上;
  3. 然后攻击者自己生成一个【伪造的】公钥,发给客户端;
  4. 客户端收到伪造的公钥后,生成加密 hash 值发给服务器;
  5. 攻击者获得加密 hash 值,用自己的私钥解密获得真秘钥;
  6. 同时生成假的加密 hash 值,发给服务器;
  7. 服务器用私钥解密获得假秘钥;
  8. 服务器用假秘钥加密传输信息;

防范方法:

服务器在发送浏览器的公钥中加入 CA 证书,浏览器可以验证 CA 证书的有效性;(现有 HTTPS 很难被劫持,除非信任了劫持者的 CA 证书)。

关于HTTPS防火墙:

原理:HTTPS防火墙要做的一件事就是,强制安装一个证书到“受信任”列表中。有了这个“受信任”证书,HTTPS防火墙,也就是中间人,即可把任何想要监听的网站的证书,都替换成这个“受信任”证书,之后通过HTTPS防火墙内置的私钥,解开客户端到服务器之间的全部加密通信。

preview

危险:这种方式是有很大的安全风险的,因为,如果HTTPS防火墙本身被攻击,私钥泄漏,那么在公司上网将不再安全,所有HTTPS网页上的密码,都可能有泄漏的危险,比如知乎、微博等网站,仅仅依靠HTTPS加密来保证登录密码的安全,这些密码都不再安全。

防火墙服务器容易被访问坍塌。

淘汰问题:主流的网站和app都在做证书锁定。就是客户端会检查ssl通信用的公钥是不是服务器的公钥

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值