安全的超文本传输协议(Hyper Text Transfer Protocol over Secure Socket Layer,简称https ),HTTPS 是 HTTP 的安全版,是使用TLS/SSL 加密的 HTTP 协议。
# HTTP与HTTPs
# HTTP
超文本传输协议(hypertext transfer protocol,简称http),是互联网上应用最为广泛的一种网络协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)。
HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此 HTTP 协议不适合传输一些敏感信息,比如信用卡号、密码等。 为了解决 HTTP 协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议 HTTPS。
# HTTPS
安全的超文本传输协议(Hyper Text Transfer Protocol over Secure Socket Layer,简称https ),HTTPS 是 HTTP 的安全版,是使用TLS/SSL 加密的 HTTP 协议。
主要作用:
- 建立一个信息安全通道,来保证数据传输的安全
- 确认网站的真实性
# HTTP与HTTPS区别
https 协议需要到 ca 申请证书,目前市面上的免费证书也不少,收费的也都比较贵。
http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 tsl/ssl 加密传输协议。
http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。
# HTTP报文结构体是什么结构?
# 请求行
请求方法、URL(请求地址)、协议版本( http 版本号,比较流行的是 Http1. 1 版本)
# 请求方法
方法 | 描述 |
---|---|
GET | 请求指定的页面信息,并返回实体主体。 |
POST | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 |
HEAD | 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头 |
PUT | 从客户端向服务器传送的数据取代指定的文档的内容 |
DELETE | 请求服务器删除指定的页面 |
CONNECT | HTTP/1. 1协议中预留给能够将连接改为管道方式的代理服务器 |
OPTIONS | 允许客户端查看服务器的性能 |
TRACE | 回显服务器收到的请求,主要用于测试或诊断 |
# URL
统一资源定位符( Uniform Resource Locator ,简称URL),URL 是一种 URI,它标识一个互联网资源,并指定对其进行操作或获取该资源的方法。可能通过对主要访问手段的描述,也可能通过网络“位置”进行标识。
大部分URL遵循一种标准格式,该格式包含三个部分:
- 方案:方案告知Web客户端怎样访问资源
- 主机:告知Web客户端资源位于何处。
- 路径:指定服务器上某个资源,说明了请求的是服务器上的哪个特定的资源。
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
组成 | 描述 | 默认值 |
---|---|---|
方案 | 访问服务器以获取资源时要使用哪种协议 | - |
用户 | 某些方案访问资源时需要的用户名 | 匿名 |
密码 | 用户名后面可能要包含的密码,中间由冒号分隔 | <E-mail 地址> |
主机 | 资源宿主服务器的主机名或点分IP地址 | - |
端口 | 资源宿主服务器正在监听的端口号。很多方案都有默认端口号 | 每个方案特有 |
路径 | 服务器上资源的本定名,由斜杠将其与前面的URL组件分隔开来。路径组件的语法是与服务器和方案有关。 | - |
参数 | 某些方案会用这个组件来指定输入参数。参数为名/值对。URL中可以包含多个参数字段,它们相互之间以与路径的其余部分之间用分号(; )分隔。 | - |
查询 | 某些方案会用这个组件传递参数以激活因公程序。查询组件的内容没有通用格式。用字符”?”将其与URL的其余部分分隔开来。 | - |
片段 | 一小片或者一部分资源的名字。引用对象时,不会将frag字段传送给服务器。这个字段是在客户端内部使用的。通过字符”#”将其与URL的其余部分分隔开来。 | - |
URI(uniform resource identifier),统一资源标识符,用来唯一的标识一个资源,包括URL和URN。
URN(uniform resource name), 统一资源命名,是通过名字来标识资源
# 协议版本
协议版本 | 描述 |
---|---|
http 0. 9 | 只有一个命令GET;没有HEADER等描述数据的信息;服务器发送完毕就关闭TCP连接 |
http 1. 0 | 增加很多命令;增加status code 和HEADER多字符集支持、多部分发送、权限、缓存等 |
http 1. 1 | 持久连接keep-alive ;pipeline;增加host等命令;物理机可以部署不同服务 |
http 2. 0 | 所有数据以二进制传输同一个连接里面发送多个请求不再需要按照顺序;头信息压缩以及托送等 提高效率等功能 |
https://blog.csdn.net/qq_22238021/article/details/81197157
# 请求头
请求的附加信息,以键值对形式组成,键和值用英文冒号“:”分隔。
# 常见请求头
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言 |
Host | 指定资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与If-Match相反) |
Referer | 对请求中URI的原始获取方 |
User-Agent | Http客户端程序的信息 |
# 全请求头
Header | 描述 | 实例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en, zh |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1. 1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定的服务器行为 | Expect: 100-continue |
From | 发出请求的用户的Email | From: user@email. com |
Host | 指定请求的服务器的域名和端口号 | Host: www. zcmhi. com |
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息通过代理和网关传送的时间 | Max-Forwards: 10 |
Pragma | 用来包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 连接到代理的授权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后, 即来路 | Referer: http://www.zcmhi.com/archives/71.html |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers, deflate; q=0. 5 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2. 0, SHTTP/1. 3, IRC/6. 9, RTA/x11 |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5. 0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1. 0 fred, 1. 1 nowhere. com (Apache/1. 1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
# 请求体
多个请求参数的数据。实体中可以放参数的序列化形式(a=1&b=2这种),或者直接放表单对象(Form Data对象,上传时可以夹杂参数以及文件。
# 响应行
协议版本,状态码,状态码描述。
# 响应头
响应报文的附加信息,由 键/值 对组成,与请求头的格式类似。
Header | 描述 | 实例 |
---|---|---|
Accept-Ranges | 表明服务器是否支持指定范围请求及哪种类型的分段请求 | Accept-Ranges: bytes |
Age | 从原始服务器到代理缓存形成的估算时间(以秒计,非负) | Age: 12 |
Allow | 对某网络资源的有效的请求行为,不允许则返回405 | Allow: GET, HEAD |
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型 | Cache-Control: no-cache |
Content-Encoding | web服务器支持的返回内容压缩编码类型。 | Content-Encoding: gzip |
Content-Language | 响应体的语言 | Content-Language: en, zh |
Content-Length | 响应体的长度 | Content-Length: 348 |
Content-Location | 请求资源可替代的备用的另一地址 | Content-Location: /index. htm |
Content-MD5 | 返回资源的MD5校验值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整个返回体中本部分的字节位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 |
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 请求变量的实体标签的当前值 | ETag: “737060cd8c284d8af7ad3082f209582d” |
Expires | 响应过期的日期和时间 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 | Location: http://www.zcmhi.com/archives/94.html |
Pragma | 包括实现特定的指令,它可应用到响应链上的任何接收方 | Pragma: no-cache |
Proxy-Authenticate | 它指出认证方案和可应用到代理的该URL上的参数 | Proxy-Authenticate: Basic |
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) |
Refresh: 5; url= http://www.zcmhi.com/archives/94.html | | Retry-After | 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 | Retry-After: 120 | | Server | web服务器软件名称 | Server: Apache/1. 3. 27 (Unix) (Red-Hat/Linux) | | Set-Cookie | 设置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 | | Trailer | 指出头域在分块传输编码的尾部存在 | Trailer: Max-Forwards | | Transfer-Encoding | 文件传输编码 | Transfer-Encoding:chunked | | Vary | 告诉下游代理是使用缓存响应还是从原始服务器请求 | Vary: * | | Via | 告知代理客户端响应是通过哪里发送的 | Via: 1. 0 fred, 1. 1 nowhere. com (Apache/1. 1) | | Warning | 警告实体可能存在的问题 | Warning: 199 Miscellaneous warning | | WWW-Authenticate | 表明客户端请求实体应该使用的授权方案 | WWW-Authenticate: Basic |
# 响应体
服务端需要传给客户端的内容:回车符、换行符和响应返回的数据。现在的接口请求时,实体中就是对于的信息的json格式,而像页面请求这种,里面就是直接放了一个html字符串,然后浏览器自己解析并渲染。
# HTTP的状态码
分类 | 描述 |
---|---|
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
# 状态码列表
状态码 | 英文名称 | 描述 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
200 | OK | 请求成功。一般用于GET与POST请求 |
201 | Created | 已创建。成功请求并创建了新的资源 |
202 | Accepted | 已接受。已经接受请求,但未处理完成 |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
400 | Bad Request | 客户端请求的语法错误,服务器无法理解 |
401 | Unauthorized | 请求要求用户的身份认证 |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 服务器无法根据客户端请求的内容特性完成请求 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
# 307、303和302区别是什么?
303和307是HTTP1. 1新加的服务器响应文档的状态码,它们是对HTTP1. 0中的302状态码的细化,主要用在对非GET、HEAD方法的响应上。
文档规定:浏览器对303状态码的处理跟原来浏览器对HTTP1. 0的302状态码的处理方法一样;浏览器对307状态码处理则跟原来HTTP1. 0文档里对302的描述一样。
303和307的存在,归根结底是由于POST方法的非幂等属性引起的。较少使用是因为于GET和HEAD方法来说,307是没必要存在的,用302或者303就可以满足需求了,307仅在POST方法的重定向上有用处。少见的原因有两方面:
POST方法重定向的使用场景太少,使得307状态码没有用武之地;
GET方法虽然常需要使用的重定向,但使用302状态码也能正确运转,再考虑到微乎其微的兼容问题(现在的浏览器支持HTTP1.1),也就没有使用303的必要了。
302
RFC1945(RFC1945),也就是HTTP1. 0在介绍302时说,如果客户端发出POST请求后,收到服务端的302状态码,那么不能自动的向新的URI发送重复请求,必须跟用户确认是否该重发,因为第二次POST时,环境可能已经发生变化,POST操作会不符合用户预期。但是,很多浏览器(user agent我描述为浏览器以方便介绍)在这种情况下都会把POST请求变为GET请求。
RFC2616(RFC2616),也就是HTTP1. 1在介绍302时说,如果客户端发出非GET、HEAD请求后,收到服务端的302状态码,那么就不能自动的向新URI发送重复请求,除非得到用户的确认。但是,很多浏览器都把302当作303处理了(注意,303是HTTP1. 1才加进来的,其实从HTTP1. 0进化到HTTP1. 1,浏览器什么都没动),它们获取到HTTP响应报文头部的Location字段信息,并发起一个GET请求。
303和 307
HTTP1. 1和HTTP1. 0的302状态码意义是一样的,浏览器对它的处理也是一样的。POST方法的重定向在未询问用户的情况下就变成GET,这种不符合文档规范的问题依然存在。实践在前而文档在后,HTTP1. 1把这种POST变GET的行为纳入了RFC文档:HTTP1. 1新加入303和307状态码。 HTTP1. 1文档中307状态码则相当于HTTP1. 0文档中的302状态码,当客户端的POST请求收到服务端307状态码响应时,需要跟用户询问是否应该在新URI上发起POST方法,也就是说,307是不会把POST转为GET的。
从网络上搜索到这个说法“303:对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。 307:对于POST请求,表示请求还没有被处理,客户端应该向Location里的URI重新发起POST请求。”,从上面的介绍可以明白,这个说法是臆想而已,文档并没有这么说,而业界是否统一如此处理,还不好说,我没有抓到过307和303的包。
文档也说到,为兼容很多HTTP1. 1之前的浏览器,服务端在需要发出303状态码时,会选择用302状态码替代;而对于307的处理,则需要在响应实体中包含信息,以便不能处理307状态码的用户有能力在新URI中发起重复请求,也就是说,把重定向的页面展示给用户,让用户去点重定向URI链接(URI现在基本就是URL)
# 502和504区别是什么?
502 bad gateway网关错误:
作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。后端服务器tomcat没有起来,应用服务的问题。
504 gateway time-out 网关超时:
作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到的响应。一般计算机中的超时就是配置错了,此处一般指nginx做反向代理服务器时,所连接的服务器tomcat无响应导致的。
# 200和304区别是什么?
在客户端非强制刷新,如点击刷新按钮或按f5的情况下,服务器端会根据request头中:If-Modified-Since字段的时间与文件的实际修改时间进行比较;
- 如果修改时间比If-Modified-Since时间要新,则服务器会认为文件已经修改过了,向客户端返回全量的数据,客户端本地的缓存失效,状态码为200。
- 如果修改时间比If-Modified-Since时间要旧,则服务器会认为文件并未修改过,并且只会向客户端写回头文件,不返回文件数据,客户端使用本地缓存,状态码为304。
200
在嗅探抓包过程中,常见的有两种200和304。这两个状态码都关系到能否获取重要信息。当客户第一次请求服务器资源,服务器成功返回资源,这时状态码为200。所以,状态码为200的数据包往往包含用户从服务器获取的数据。
状态码200:请求已成功,请求所希望的响应头或数据体将随此响应返回。即返回的数据为全量的数据,如果文件不通过GZIP压缩的话,文件是多大,则要有多大传输量。
304
每个资源请求完成后,通常会被缓存在客户端,并会记录资源的有效时间和修改时间。当客户再次请求该资源,客户端首先从缓存中查找该资源。如果该资源存在,并且在有效期,则不请求服务器,就不会产生对应的请求数据包。
如果不在有效期,客户端会请求服务器,重新获取。服务器会判断修改时间,如果没有修改过,就会返回状态码304,告诉客户端该资源仍然有效,客户端会直接使用缓存的资源。针对304的响应,渗透人员可以分析对应的请求包,获取资源路径。如果该资源不限制访问,就可以直接请求获取。否则,就需要进行Cookie劫持,进行获取。
状态码304:客户端和服务器端只需要传输很少的数据量来做文件的校验,如果文件没有修改过,则不需要返回全量的数据。
但发生了客户端强制刷新,如ctrl+f5这种情况下,所有的缓存策略就会失效,服务器端都会返回200;
# 301和302的区别
301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。
302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。
# HTTP2三要素
# 流
流(Stream),服务器和客户端在HTTP/2连接内用于交换帧数据的独立双向序列,逻辑上可看做一个较为完整的交互处理单元,即表达一次完整的资源请求-响应数据交换流程;一个业务处理单元,在一个流内进行处理完毕,这个流生命周期完结。
# 特点
双向性:一个HTTP/2连接可同时保持多个打开的流,任一端点交换帧,可同时发送和接受数据
流可被客户端或服务器单独或共享创建和使用
流可被任一端关闭
有序性:在流内发送和接收数据都要按照顺序
流的标识符自然数表示,1~2^31区间,有创建流的终端分配
并行性:流与流之间逻辑上是并行、独立存在。
# 组成
![流](/img/browser/流. png)
# 流的优先级
流的优先级在于允许终端向对端表达所期待的给予具体流更多资源支持的意见的表达,不能保证对端一定会遵守,非强制性需求建议;默认值16。在资源有限时,可以保证基本数据的传输。
优先级改变:
- 终端可在新建的流所传递HEADERS帧中包含优先级priority属性
- 可单独通过PRIORITY帧专门设置流的优先级属性
# 流依赖
- 流与流之间存在依赖、被依赖关系。所有流默认依赖流0x0;推送流依赖于传输PUSH_PROMISE的关联流。
- 依赖权重值1~256区间,对于依赖同一父级的子节点,应该根据权重比列进行分配资源。
- 对于依赖同一个父级流的子节点被指定相关权重值,以及可用资源的分配比重。子节点之间顺序不固定。
A A
/ \ ==> /|\
B C B D C
2
3
- 一旦设置独家专属标志(exclusive flag)将为现有依赖插入一个水平的依赖关系,其父级流只能被插入的新流所依赖。比如流D设置专属标志并依赖于流A
A
A |
/ \ ==> D
B C / \
B C
2
3
4
5
流的依赖树形模型,底层的流只能等到上层流被关闭或无法正常运转/失效时,才会被分配到资源
流无法依赖自身,否则为PROTOCOL_ERROR流错误
在流依赖树形模型中,父节点优先级,以及专属依赖流的加入等,都会导致已有优先级重排序
? ? ? ?
| / \ | |
A D A D D
/ \ / / \ / \ |
B C ==> F B C ==> F A OR A
/ \ | / \ /|\
D E E B C B C F
| | |
F E E
(intermediate) (non-exclusive) (exclusive)
2
3
4
5
6
7
8
9
10
# 流优先级状态管理
流的依赖树形模型,任一节点被移除,都需要重建优先级顺序,重新分配资源
终端建议在流关闭一段时间内保留优先级信息,减少潜在的指派错误
处于"idle"状态流可被指派默认优先级16,这时可以变成其它流的父节点,可以指派新的优先级值
终端持有的流优先级信息不受SETTINGS_MAX_CONCURRENT_STREAMS限制,但可能会造成终端状态维护负担,其数量可以被限制不多于SETTINGS_MAX_CONCURRENT_STREAMS所定义数量
优先级状态信息的维持在负载较高时可以被丢弃,以减少资源占用。
终端若有能力保留足够状态,在接收到PRIORITY帧目的修改已被关闭流的优先级时,可以为其子节点重建优先级顺序
# 流量控制
多路复用会引入资源竞争,流量控制可以保证流之间不会严重影响到彼此。流量控制通过使用WINDOW_UPDATE帧实现,可作用于单个流以及整个的连接。一些原则如下:
逐跳,具有方向性
不能够被禁止
初始窗口值为65535字节,针对单个流,以及整个连接都有效
基于WINDOW_UPDATE帧传输实现,接收端通告对端准备在流/连接上接收的字节数
接收端完全控制权限,接受端可通告针对流/连接的窗口值,发送者需要遵守
目前只有DATA帧可被流量控制,仅针对其有效负载计算;超出窗口值,其负载可以为空
- 流量控制是为解决线头阻塞问题,同时在资源约束情况下保护一些操作顺利进行,针对单个连接,某个流可能被阻塞或处理缓慢,但同时不会影响到其它流上正在传输的数据
- 虽然流量控制可以用来限制一个对等端消耗的内存,但若在不知道网络带宽延迟乘积的情况下可能未必能够充分利用好网络资源
- 流量控制机制很复杂,需要考虑大量的细节,实现很困难
# 流的影响因素:
流的优先级(priority)属性建议终端(客户端+服务器端)需要按照优先级值进行资源合理分配,优先级高的需要首先处理,优先级低的可以稍微排排队,这样的机制可保证重要数据优先处理。
流的并发数(或者说同一时间存在的流的个数)初始环境下不少于100个
流量控制阀协调网络带宽资源利用,由接收端提出发送端遵守其规则
流具有完整的生命周期,从创建到最终关闭,经历不同阶段
# 注意事项
HTTP/2规范中所定义的流概念、属性很复杂,在请求量很大以及应对海量并发的情况下,整个连接的流量控制+单个流的流量控制+流的状态+流优先级属性+优先级的状态+流依赖树形模型等一系列新特性,可能会造成:
服务器端/客户端单个连接内存占用过高,维护一个长连接的成本比以往多了若干倍
流量控制是一个复杂功能,实现不好会导致一端流量窗口值已被耗尽,需要等待客户端发送新的流控窗口值,若有热数据进行发送,需要等待成本,无形中增加了额外的交互步骤
流依赖和优先级重排序等,无形中增加了程序的复杂度,处理不好触发潜在BUG
为了性能和内存考虑,很多知名应用不见得有动力实现全部特性,流的一些高级特性毕竟有些过于理想化,诸如当前实现列表:Implementations,可以看出一二
实际非浏览器环境,诸如HTTP API等,实际上仅需要部分关键特性,这属于情理之中的选择
凡是状态皆需要维护,无论横向还是纵向的扩展都需要倍加注意;无状态才是最有利于扩展。
# 2. 帧
帧是数据交换的基本单元,必须归属于某个流才能被发送。
- HTTP/1 的请求和响应报文,是由起始行、首部和正文组成,换行符分隔。
- HTTP/2 将请求和响应数据分割为更小的帧,并对它们采用二进制编码。易于解析。
帧的行为以及END_STREAM标志位都会对流的状态的产生变化。因为流由各个端独立创建,没有协商,消极后果就是(两端无法匹配的流的状态)导致发送完毕RST_STREAM帧之后“关闭”状态受限,因为帧的传输和接收需要一点时间,所以有以下要求:
- 针对具体状态中出现没有允许出现的帧,需要作为协议错误(PROTOCOL_ERROR)类型的连接错误处理
- 在流的任何状态下,PRIORITY帧都可以被发送或接收
- 未知帧可以被忽略
# 帧状态
idle,所有流的开始状态值
- 发送/接收HEADERS帧,进入open状态
- PUSH_PROMISE帧只能在已有流上发送,导致创建的本地推送流处于"resereved(local)"状态
- 在已有流上接收PUSH_PORMISE帧,导致本地预留一个流处于"resereved(remote)"状态
- HEADERS/PUSH_PROMISE帧以及后面的零个或多个CONTINUATION帧,只要携带有END_STREAM标志位流状态将进入"half closed"状态
- 只能接收HEADERS和PRIORITY,否则报PROTOCOL_ERROR类型连接错误
reserved,为推送保留一个流稍后使用
- reserved (local),服务器端发送完PUSH_PROMISE帧本地预留的一个用于推送流所处于的状态
- 只能发送HEADERS、RST_STREAM、PRIORITY帧
- 只能接收RST_STREAM、PRIORITY、WINDOW_UPDATE帧
- reserved (remote),客户端接收到PUSH_PROMISE帧,本地预留的一个用于接收推送流所处于的状态
- 只能发送WINDOW_UPDATE、RST_STREAM、PRIORITY帧
- 只能接收RST_STREAM、PRIORITY、HEADERS帧
- 不满足条件,需要报PROTOCOL_ERROR类型连接错误
- reserved (local),服务器端发送完PUSH_PROMISE帧本地预留的一个用于推送流所处于的状态
open,用于两端发送帧,需要发送数据的对等端需要遵守流量控制的通告。
- 每一端可以发送包含END_STREAM标志位的帧,导致流进入"half closed"状态
- 每一端都可以发送RST_STREAM帧,流进入"closed"状态
half closed
- half closed (local),发送包含有END_STREAM标志位帧的一端,流进入本地半关闭状态
- 不能发送WINDOW_UPDATE,PRIORITY和RST_STREAM帧
- 可以接收到任何类型帧
- 接收者可以忽略WINDOW_UPDATE帧,后续可能会马上接收到包含有END_STREAM标志位帧
- 接收到优先级PRIORITY帧,可用来变更依赖流的优先级顺序,有些小复杂了
- 一旦接收到包含END_STREAM标志位的帧,将进入"closed"状态
- half closed (remote),接收到包含有END_STREAM标志位帧的一端,流进入远程半关闭状态
- 对流量控制窗口可不用维护
- 只能接收RST_STREAM、PRIORITY、WINDOW_UPDATE帧,否则报STREAM_CLOSED流错误
- 终端可以发送任何类型帧,但需要遵守对端的当前流的流量控制限制
- 一旦发送包含END_STREAM标志位的帧,将进入"closed"状态
- 一旦接收或发送RST_STREAM帧,流将进入"closed"状态。
- half closed (local),发送包含有END_STREAM标志位帧的一端,流进入本地半关闭状态
closed,流的最终关闭状态
- 只允许发送PRIORITY帧,对依赖关闭的流进行重排序
- 终端接收RST_STREAM帧之后,只能接收PRIORITY帧,否则报STREAM_CLOSED流错误
- 接收的DATA/HEADERS帧包含有END_STREAM标志位,在一个很短的周期内可以接收WINDOW_UPDATE或RST_STREAM帧;超时后需要作为错误对待
- 终端必须忽略WINDOW_UPDATE或RST_STREAM帧
- 终端发送RST_STREAM帧之后,必须忽略任何接收到的帧
- 在RST_STREAM帧被发送之后收到的流量受限DATA帧,转向流量控制窗口连接处理。尽管这些帧可以被忽略,因为他们是在发送端接收到RST_STREAM之前发送的,但发送端会认为这些帧与流量控制窗口不符。
- 终端在发送RST_STREAM之后接收PUSH_PROMISE帧,尽管相关流已被重置,但推送帧也能使流变成“保留”状态。因此,可用RST_STREAM帧关闭一个不想要的承诺流
# 帧格式
帧通用格式:Header(固定9字节)+ Payload(根据帧类型变化)
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| Type (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Frame Payload (0...) ...
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
- Length: 载荷的长度, 无符号24位整型. 对于发送值大于2^14 (长度大于16384字节)的载荷, 只有在接收方设置SETTINGS_MAX_FRAME_SIZE为更大的值时才被允许
注: 帧的报头9字节不算在length里.
Type: 8位的值表示帧类型, 决定了帧的格式和语义. 协议实现上必须忽略任何未知类型的帧.
Flags: 为Type保留的bool标识, 大小是8位. 对确定的帧类型赋予特定的语义, 否则发送时必须忽略(设置为0x0).
R: 1位的保留字段, 尚未定义语义. 发送和接收必须忽略(0x0).
Stream Identifier: 31位无符号整型的流标示符. 其中0x0作为保留值, 表示与连接相关的frames作为一个整体而不是一个单独的流.
# 2-3. 帧分类
SETTINGS帧 作用:连接成功后发送的第一个帧,用于传递端点间如何通信的配置参数; 作用范围: 连接,非某个流; 发送时机:连接初始化时,双方必须发送;连接建立后,任意一方可以选择在任意时间点发送;
SETTINGS帧格式
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| 0x4 (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier/0x0 (32) |
+=+=============================+===============================+
| Identifier (16) |
+-------------------------------+-------------------------------+
| Value (32) |
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
SETTINGS参数
SETTINGS_HEADER_TABLE_SIZE (0x1): 首部压缩表的最大大小,默认值是4, 096字节;
SETTINGS_ENABLE_PUSH (0x2): 是否允许服务端推动,默认值1,表示允许;
SETTINGS_MAX_CONCURRENT_STREAMS (0x3): 指明了发送者允许的最大的并发流个数;
SETTINGS_INITIAL_WINDOW_SIZE (0x4): 流的初始窗口大小,始值为65, 535字节;
SETTINGS_MAX_FRAME_SIZE (0x5): 帧的最大值,初始值是2^14 (16, 384)字节;
SETTINGS_MAX_HEADER_LIST_SIZE (0x6): 头部列表的数量上限,初始值没有限制;
HEADER帧
作用:打开一个流,传递请求头/响应头信息(KV列表)
HEADER帧格式
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| 0x1 (8) | Flags (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier/0x0 (32) |
+=+=============================+===============================+
|Pad Length? (8)|
+-+-------------+-----------------------------------------------+
|E| Stream Dependency? (31) |
+-+-------------+-----------------------------------------------+
| Weight? (8) |
+-+-------------+-----------------------------------------------+
| Header Block Fragment (*) ...
+---------------------------------------------------------------+
| Padding (*) ...
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Flag: END_STREAM (0x1):流的结束,HEADER帧为流的最后一个数据; END_HEADERS (0x4):请求头/响应头信息的结束,一个没有设置END_HEADERS标记的HEADERS帧后面 必须(MUST) 跟着一个CONTINUATION帧; 注意: 如果请求头/响应头内容过多,需要借助于CONTINUATION帧继续传输。
CONTINUATION帧
作用:用于协助HEADERS/PUSH_PROMISE等单帧无法包含完整的报头剩余部分数据。
CONTINUATION帧格式
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| 0x9 (8) | 0x0/0x4 (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (32) |
+=+=============================================================+
| Header Block Fragment (*) |
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
注意: 一个HEADERS/PUSH_PROMISE帧后面会跟随零个或多个CONTINUATION,只要上一个帧没有设置END_HEADERS标志位,就不算一个帧完整数据的结束。 接收端处理时,必须从开始的HEADERS/PUSH_PROMISE帧到最后一个包含有END_HEADERS标志位帧结束,合并的数据才算是一份完整数据拷贝 ; 在HEADERS/PUSH_PROMISE(没有END_HEADERS标志位)和CONTINUATION帧中间,是不能够掺杂其它帧的,否则需要报PROTOCOL_ERROR错误; 标志位: END_HEADERS(0X4)表示报头块的最后一个帧,否则后面还会跟随CONTINUATION帧。
DATA帧
作用: 传送请求或相应的消息体;
DATA帧格式
+-----------------------------------------------+
| Length (24) |
+---------------+---------------+---------------+
| 0x0 (8) | Flag (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============+===============================================+
|Pad Length (8)|
+---------------+-----------------------------------------------+
| Data (*) ...
+---------------------------------------------------------------+
| Padding (*) ...
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
10
11
12
13
PUSH_PROMISE帧
作用: Server Push功能相关的帧;
PING帧 作用: 心跳或测量网络耗时;
PING帧格式
+-----------------------------------------------+
| 0x8 (24) |
+---------------+---------------+---------------+
| 0x6 (8) | Flag (8) |
+-+-------------+---------------+-------------------------------+
|R| 0x0 (32) |
+=+=============================================================+
| Opaque Data (64) |
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
Flag: ACK(0x1) 一旦设置,表示此PING帧为接收者响应的PING帧,非发送者;
7. PRIORITY帧
作用: 达了发送方对流优先级权重的建议值,在流的任何状态下都可以发送,包括空闲或关闭的流;
PRIORITY帧格式
+-----------------------------------------------+
| 0x5 (24) |
+---------------+---------------+---------------+
| 0x2 (8) | 0x0 (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
|E| Stream Dependency (31) |
+-+-------------+-----------------------------------------------+
| Weight (8) |
+---------------+
2
3
4
5
6
7
8
9
10
11
8. WINDOW_UPDATE帧
作用: 用于实现flow control的帧,可以作用在每个单独的流上,或者整个连接上。
注意: 目前流控只会影响到DATA数据帧;
9. RST_STREAWM帧
作用: 表明发生了错误,用于关闭流;
RST_STREAWM帧格式
+-----------------------------------------------+
| 0x4 (24) |
+---------------+---------------+---------------+
| 0x3 (8) | 0x0 (8) |
+-+-------------+---------------+-------------------------------+
|R| Stream Identifier (31) |
+=+=============================================================+
| Error Code (32) |
+---------------------------------------------------------------+
2
3
4
5
6
7
8
9
10. GOAWAY帧
作用: 一端通知对端较为优雅的方式停止创建流,同时还要完成之前已建立流的任务。
# 多路复用
多路复用,就是在一个 TCP 连接中可以存在多条流。换句话说,也就是可以发送多个请求,对端可以通过帧中的标识知道属于哪个请求。通过这个技术,可以避免 HTTP 旧版本中的队头阻塞问题,极大的提高传输性能.
# 帧、流与多路复用的关系
在 HTTP/2 中,帧和流的概念提出,就是为了实现多路复用。帧代表着最小的数据单位,每个帧会标识出该帧属于哪个流,流也就是多个帧组成的数据流。
- 一个连接同时被多个流复用;
- 一个流代表一次完整的请求/响应过程,包含多个帧;
- 一个消息被拆分封装成多个帧进行传输;
# 优点
- 减少服务端连接压力,减少占用内存,提升连接吞吐量;
- 连接数的减少改善了网络拥塞状况,慢启动时间减少,拥塞和丢包恢复速度更快;
- 避免连接频繁创建和关闭(三次连接、四次挥手)
# HTTP2和HTTP1. 1的区别?
# 区别概览
![http12区别](/img/browser/http12区别. png)
二进制分帧:HTTP/2采用二进制格式而非文本格式
多路复用 :HTTP/2是完全多路复用的,而非有序并阻塞的
首部压缩:移除了重复和传输重复数据的成本
服务端推送:HTTP/2让服务器可以将响应主动“推送”到客户端缓存中
# HTTP2新特性
- 二进制分帧(Binary framing layer)
是二进制协议而不是文本协议。不再可读,也不可无障碍的手动创建,改善的优化技术现在可被实施
- 多路复用 (Multiplexing)
并行的请求能在同一个链接中处理,移除了HTTP/1. x中顺序和阻塞的约束
- 单一连接(One connection per origin)
流的概念实现了单连接上多请求 - 响应并行,解决了线头阻塞的问题,减少了 TCP 连接数量和 TCP 连接慢启动造成的问题
- 数据流优先级(Stream prioritization)
客户端还可以指定数据流的优先级,优先级越高,服务器就会越早响应
- 首部压缩(Header Compression)
headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本
- 流控 (Flow control)
在不改变协议的情况下允许使用多种流量控制算法
- 服务端推送(Server Push)
其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求
# 二进制分帧/单一连接/多路复用
http2代替原来的序列和阻塞机制。所有就是请求的都是通过一个 TCP连接并发完成。
# http1. 1和http2下发起请求的过程
![http请求](/img/browser/http请求. png)
# http1. 1的过程
浏览器请求 url -> DNS解析域名 -> TCP连接 ->发送请求 -> 服务器接受处理并返回数据 -> 浏览器解析、渲染文件 -> TCP断开连接
存在问题:
- 每次请求都需要建立一次 HTTP 连接(3次握手4次挥手),消耗时间长
为了解决这个问题, HTTP 1. 1 中提供了 Keep-Alive,允许我们建立一次 HTTP 连接,来返回多次请求数据。
- HTTP 1.1 基于串行文件传输数据,请求必须是有序的,所以实际上我们只是节省了建立连接的时间,而获取数据的时间并没有减少。
最大并发数问题,假设我们在 Apache 中设置了最大并发数 300,而因为浏览器本身的限制,比如chrome最大请求数为 6,那么服务器能承载的最高并发数是 50
# HTTP/2 引入二进制数据帧和流
其中帧对数据进行顺序标识,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据。对同一域名下所有请求都是基于流,也就是说同一域名不管访问多少文件,也只建立一路连接。
Apache的最大连接数为300,因为有了这个新特性,最大的并发就可以提升到300,比原来提升了6倍
# 服务器推送
由于HTTP/2启用了对客户端初始GET请求的多个并发响应,因此服务器可以将资源与请求的HTML页面一起发送到客户端,从而在客户端请求之前提供资源,而不用等到浏览器解析到相应位置发起请求再响应。
服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML再发送这些请求。服务端可以主动推送,客户端也有权利选择接收与否。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。
# 首部压缩
HTTP 1. 1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。HTTP/2对消息头采用HPACK(专为http2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1. x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。
HTTP 每一次通信都会携带一组头部,用于描述这次通信的的资源、浏览器属性、cookie 等。为了减少这块的开销并提升性能, HTTP/2会压缩这些首部:
- HTTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送;
- 首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新;
- 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值。
# 流量控制
流量控制的目标是:在不改变协议的情况下允许使用多种流量控制算法。管理如何基于优先级发送请求和响应;选择如何避免请求的队首阻塞;管理新流的创建。为这些选择的算法可以与任何流量控制算法交互。
流量控制是特定于一个连接的。每种类型的流量控制都是在单独的一跳的两个端点之间的,并不是在整个端到端的路径上的。(这里的一跳指的是HTTP连接的一跳,而不是IP路由的一跳)
流量控制是基于WINDOW_UPDATE帧的。接收方公布自己打算在每个流以及整个连接上分别接收多少字节。这是一个以信用为基础的方案。
流量控制是有方向的,由接收者全面控制。接收方可以为每个流和整个连接设置任意的窗口大小。发送方必须尊重接收方设置的流量控制限制。客户方、服务端和中间代理作为接收方时都独立地公布各自的流量控制窗口,作为发送方时都遵守对端的流量控制设置。
无论是新流还是整个连接,流量控制窗口的初始值是65535字节。
帧的类型决定了流量控制是否适用于帧。目前,只有DATA帧服从流量控制,所有其它类型的帧并不消耗流量控制窗口的空间。这保证了重要的控制帧不会被流量控制阻塞。
流量控制不能被禁用。
HTTP/2只定义了WINDOW_UPDATE帧的格式和语义,并没有规定接收方如何决定何时发送帧、发送什么样的值,也没有规定发送方如何选择发送包。具体实现可以选择任何满足需求的算法。
# 数据流优先级
HTTP/2 里的每个 stream 都可以设置依赖 (Dependency) 和权重,可以按依赖树分配优先级,解决了关键请求被阻塞的问题
# 总结
http1. 1 提高性能的关键是低延迟而不是高带宽。 http 2. 0 所有的请求共用一个连接,可以更有效的使用tcp连接,通过带宽来提升http性能;可以减少服务链接的压力,内存减少了,链接吞吐量大了;解决浏览器连接数有限的问题;资源合并减少请求的优化手段在http2. 0来说是没有效果的。
# HTTPS建立连接的过程
![https过程](/img/browser/https过程. gif)
客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
Web服务器利用自己的私钥解密出会话密钥。
Web服务器利用会话密钥加密与客户端之间的通信。
# HTTPS加密算法
# 非对称加密算法
对称加密是指加密与解密的使用同一个密钥的加密算法。例如:RSA,DSA/DSS
# 对称加密算法
非对称加密使用的是两个密钥,公钥与私钥,我们会使用公钥对网站账号密码等数据进行加密,再用私钥对数据进行解密。这个公钥会发给查看网站的所有人,而私钥是只有网站服务器自己拥有的。例如:AES,RC4,3DES
# 参考
https://www.cnblogs.com/williamjie/p/11075565.html https://blog.csdn.net/alexshi5/article/details/80379086 https://segmentfault.com/a/1190000011172823 https://github.com/abbshr/rfc7540-translation-zh_cn