做网站过时了,网站后台管理模板下载,wordpress添加默认头像,php用户管理系统目录
一、HTTP基本概念
二、GET 与 POST
2.1、GET 与 POST 有什么区别#xff1f;
2.2、GET 和 POST 方法都是安全和幂等的吗#xff1f;
三、HTTP 缓存
3.1、强制缓存#xff1a;
3.2、协商缓存
四、HTTP 特性
4.1、HTTP/1.1
4.1.1、HTTP/1.1 的优点
4.1.2、HTT…目录
一、HTTP基本概念
二、GET 与 POST
2.1、GET 与 POST 有什么区别
2.2、GET 和 POST 方法都是安全和幂等的吗
三、HTTP 缓存
3.1、强制缓存
3.2、协商缓存
四、HTTP 特性
4.1、HTTP/1.1
4.1.1、HTTP/1.1 的优点
4.1.2、HTTP/1.1 的缺点
4.1.3、HTTP/1.1 的性能
五、HTTP 与 HTTPS
5.1、HTTP 与 HTTPS 的区别
5.2、HTTPS 解决了 HTTP 的哪些问题呢
5.3、HTTPS 是如何建立连接的
5.4、HTTPS 的应用数据是如何保证完整性的
5.5、HTTPS 就一定安全可靠吗
5.6、为什么抓包工具能够截取 HTTPS 数据
六、HTTP/1.1、HTTP/2、HTTP/3 的演变
6.1、HTTP/1.1 相比 HTTP/1.0 提高了什么性能
6.2、HTTP/2 的优化
6.3、HTTP/2 的缺陷
6.4、HTTP/3 做了哪些优化
七、HTTP/1.1 如何优化
7.1、避免发送 HTTP 请求
7.2、如何减少 HTTP 请求次数
7.2.1、减少重定向次数
7.2.2、和并请求
7.2.3、延迟发送请求
7.3、如何减少 HTTP 响应的数据大小
八、HTTPS RSA 握手解析
RSA 握手握手过程
TLS 第一次握手
TLS 第二次握手
TLS 第三次握手
TLS 第四次握手
RSA 算法的缺陷
九、优化 HTTPS 一、HTTP基本概念
HTTPHyperText Transfer Protocol是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。
HTTP常见的状态码有 HTTP 常见的字段
Host 字段客户端发送请求时用来指定服务器的域名Content-Length 字段服务器在返回数据时会有 Content-Length 字段表明本次回应的数据长度HTTP 协议通过设置回车符换行符作为 HTTP header 的边界通过 Content-Length 字段作为 HTTP body 的边界这两个方式都是为了解决”粘包“的问题Connection 字段最常用于客户端要求服务端使用【HTTP 长连接】机制以便其他请求复用它的特点就是只要任意一端没有明确提出断开连接则保持 TCP 连接状态Content-Type 字段用于服务器回应时告诉客户端本次数据是什么格式Content-Encoding 字段说明数据的压缩方法表示服务器返回的数据使用了什么压缩格式
二、GET 与 POST
2.1、GET 与 POST 有什么区别
GET 可以存在 Cache 中POST 不可以GET 请求在 URL 中传递的参数是有长度限制的POST 对长度没有限制GET 参数通过 URL 传递POST 放在 RequestBody 中GET 请求参数会完整的保留在浏览器的历史记录中POST 请求的参数不会保留理论上 POST 要比 GET 安全毕竟传输参数时 URL 不可见GET 会产生一个 TCP 数据包POST 产生两个 TCP 数据包对于 GET 请求浏览器会把 HTTP Header 和 Data 一起发送出去服务器响应 200请求成功对于 POST 请求浏览器会先发送 Header 服务器会响应 100已经收到请求的第一部分正在等待其余部分浏览器再次发送 Data 服务器返回 200请求成功。但并不是所有的浏览器都会在 POST 中发送两次包FireFox 就只发送一次
2.2、GET 和 POST 方法都是安全和幂等的吗
安全和幂等的概念
在 HTTP 协议里安全是指请求方法不会破坏服务器上的资源幂等意思是多次执行相同的操作结果都是相同的
如果从规范定义来看
GET 方法就是安全且幂等的因为它是只读操作无论操作多少次服务器上的数据都是安全的且每次的结果都是相同的。所以可以对 GET 请求的数据做缓存这个缓存可以做到浏览器本身上彻底避免浏览器发请求也可以做到代理上而且在浏览器中 GET 请求可以保存为书签POST 因为是新增或者提交数据的操作会修改服务器上的资源所以是不安全的且多次提交数据就会创建多个资源所以不是幂等的。所以浏览器一般不会缓存 POST 请求也不能把 POST 请求保存为书签
三、HTTP 缓存
避免发送 HTTP 请求的方法就是通过缓存技术HTTP 设计者早在之前就考虑到了这点因此 HTTP 协议的头部有不少是针对缓存的字段HTTP 缓存有两种实现方式分别是强制缓存和协商缓存。
3.1、强制缓存
强缓存是指只要浏览器判断缓存没有过期则直接使用浏览器的本地缓存决定是否使用缓存的主动性在浏览器这边。
强缓存是依赖下面两个 HTTP 响应头部Response Header字段实现的都用来表示资源在客户端缓存的有效期
Cache-Control是一个相对时间Expires是一个绝对时间
如果 HTTP 响应头部同时有 Cache-Control 和 Expires 字段的话Cache-Control 的优先级高于 Expires。
Cache-Control 选项更多一些设置更加精密所以建议使用 Cache-Control 来实现强缓存流程如下
当浏览器第一次请求访问服务器资源时服务器会在返回这个资源的同时在 Response 头部加上 Cache-Control Cache-Control 中设置了过期时间的大小浏览器再次请求访问服务器中的该资源时会先通过请求资源的时间与 Cache-Control 中设置的过期时间大小来计算出该资源是否过期如果没有则使用该缓存都则重新请求服务器服务器再次收到请求之后会再次更新 Response 头部的 Cache-Control
3.2、协商缓存
当我们在浏览器使用开发者工具时可能会看到某些请求的响应码是 304 这个是告诉浏览器可以使用本地缓存的资源通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。
协商缓存可以基于两种头部来实现
第一种请求头部的 If-Modified-Since 字段与响应头部中的 Last-Modified 字段实现这两个字段的意思是
响应头部中的 Last-Modified 标示这个响应资源的最后修改时间
请求头部中的 If-Modified-Since 当资源过期了发现响应头中具有 Last-Modified 声明则再次发起请求的时候带上 Last-Modified 的时间服务器收到请求后发现有 If-Modified-Since 则与被请求资源的最后修改时间进行对比Last-Modified如果最后修改时间较新大说明资源又被修改过则返回最新资源HTTP 200 OK如果最后修改时间较旧小说明资源无新修改响应 HTTP 304 走缓存。
第二种请求头部中的 If-None-Match 字段与响应头部中的 ETag 字段这两个字段的意思是
响应头部中 ETag 唯一标识响应资源
请求头部中的 If-None-Match当资源过期时浏览器发现响应头中有 ETag则再次向服务器发起请求时会将请求头 If-None-Match 值设置为 ETag 的值。服务器收到请求后进行比对如果资源没有变化返回 304如果资源变化了返回 200。
第一种方式是基于时间实现的第二种方式是基于一个唯一标识实现的相对于后者可以更加准确地判断文件内容是否被修改避免由于时间篡改导致的不可靠的问题。
如果第一次请求资源的时候服务端返回的 HTTP 响应头部同时有 ETag 和 Last-Modified 字段那么客户端再下一次请求的时候如果带上了 ETag 和 Last-Modified 字段信息给服务端这时 ETag 的优先级更高也就是服务端会判断 ETag 是否变化了如果 ETag 有变化则不用在判断 Last-Modified 了如果 ETag 没有变化然后再看 Last-Modified。
为什么 ETag 的优先级更高呢这是因为它主要能解决 Last-Modified 几个比较难的问题
在没有修改文件内容情况下文件的最后修改时间可能也会有变化这会导致客户端认为这文件被改动了从而重新请求可能有些文件是在秒级以内修改的If-Modified-Since 能检查到的粒度是秒级的使用 ETag 就能够保证在这种需求下客户端在 1 秒内能够刷新多少次有些服务器不能精确获取文件的最后修改信息
注意协商缓存这两个字段都需要配合强制缓存中 Cache-Control 字段来使用只有在未能命中强制缓存的时候才能发起带有协商缓存字段的请求。
当使用 ETag 字段实现的协商缓存的过程
当浏览器第一次请求访问服务器资源时服务器会在返回这个资源的同时在 Response 头部加上 ETag 唯一标识这个唯一标识的值是根据当前请求的资源生成的当浏览器再次请求访问服务器中的该资源时首先会检查强制缓存是否过期 如果没有过期则直接使用本地缓存如果过期了会在 Response 头部加上 If-None-Match 字段该字段的值就是 ETag 唯一标识服务器再次收到请求后会根据请求中的 If-None-Match 值与当前请求的资源生成唯一标识进行比较 如果值相等则返回 304 Not Modified 不会返回资源如果不相等则返回 200 状态码和返回资源并在 Response 头部加上新的 ETag 唯一标识如果浏览器收到 304 的请求响应状态码则会从本地缓存中加载资源否则更新资源
四、HTTP 特性
4.1、HTTP/1.1
4.1.1、HTTP/1.1 的优点
①、简单
HTTP 基本的报文格式就是 header body 头部信息也是 key-value 简单文本的形式易于理解降低了学习和使用的门槛
②、灵活和易于拓展
HTTP 协议中的各类请求方法、URI/URL 、状态码、头字段等每个组成要求都没有被固定死都允许开发人员自定义和扩充。同时由于 HTTP 是工作在应用层则它下层可以随意变化比如
HTTPS 就是在 HTTP 与 TCP 层之间增加了 SSL/TLS 安全传输层
HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议而到了 HTTP/3.0传输协议改用了 UDP 协议
③、应用广泛和跨平台
4.1.2、HTTP/1.1 的缺点
①、无状态双刃剑
无状态的好处就是服务器不会记忆 HTTP 的状态所以不需要额外的资源来记录状态信息这能减轻服务器的负担能够把更多的 CPU 和内存用来对外提供服务。
坏处就是既然服务器没有记忆能力它在完成有关联性的操作时会非常麻烦每操作一次就要验证一次对于无状态的问题解决方法比较简单的方式就有 Cookie 技术。Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态相当于在客户端第一次请求之后服务器会发下一个装有客户信息的【小贴纸】后续客户端请求服务器的时候带上【小贴纸】服务器就能够认得了。
②、明文传输双刃剑
明文传输意味着在传输过程中的信息是可方便阅读的比如抓包都可以直接肉眼查看为我们调式工作带来了极大的遍历。但正因为如此HTTP 的所有信息都暴露在外相当于信息裸奔。在传输的过程之中信息的内容都毫无隐私可言很容易被窃取。
③、不安全
通信使用明文传输内容可能被监听不验证通信方的身份有可能遭遇伪装无法访问报文的完整性所以有可能已遭篡改
4.1.3、HTTP/1.1 的性能
HTTP 协议是基于 TCP/IP 并且使用了【请求-应答】的通信模式所以性能的关键就在此处。
长连接早期 HTTP/1.0 性能上的很大问题就是没法起一个请求就要新建一次 TCP 连接而且是串航请求做了所谓的 TCP 连接建立和断开增加了通信的开销。HTTP/1.1 提出了长连接的通信方式也叫持久连接好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销减轻了服务端的负载
管道网络传输即可在同一个 TCP 连接里客户端可以发起多个请求只要第一个请求发送出去了不必等其回来就可以发第二个请求出去可以减少整体的响应时间。但是服务器必须按照接受请求的顺序发送对这些管道化请求的响应。所以 HTTP /1.1 管道解决了请求的队头阻塞但是没有解决响应的队头阻塞
队头阻塞当顺序发送的请求序列中的一个请求因为某种原因被阻塞时在后面排队的所有请求也一同被阻塞了会招致客户端一直请求不到数据这就是【队头阻塞】
五、HTTP 与 HTTPS
5.1、HTTP 与 HTTPS 的区别
HTTP 是超文本传输协议信息是明文传输存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议使得报文能够加密传输HTTP 连接建立相对简单TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后还需要进行 SSL/TLS 的握手过程才可进入加密报文传输两者的默认端口不一致HTTP 默认端口是 80 HTTPS的默认端口是 443HTTPS 协议需要向 CA 证书权威机构申请数字证书来保证服务器的身份是可信的
5.2、HTTPS 解决了 HTTP 的哪些问题呢
窃听风险比如通信链路上可以获取通信内容篡改风险比如强制植入垃圾广告视觉污染冒充风险比如冒充淘宝钱容易没
如何解决的呢
信息加密交互信息无法被篡改校验机制无法篡改通信内容篡改了就无法显示身份证书证明某个网站是正版的
具体的实现方法
混合加密实现了信息的机密性解决了窃听的风险摘要算法的方式来实现完整性能够为数据生成独一无二的【指纹】指纹用于校验数据的完整性解决了篡改的风险将服务器公钥放入到数字证书中解决了冒充的风险
混合加密
HTTPS 采用的是对称加密和非对称加密结合的【混合加密】方式
在通信建立前采用非对称加密的方式交换【会话密钥】后续就不再使用非对称加密
在通信过程中全部使用对称加密的【会话密钥】的方式加密明文数据
采用混合加密的方式的原因
对称加密只使用一个密钥运算速度快密钥无法保密无法做到安全的密钥交换非对称加密使用两个密钥公钥和私钥公钥可以任意分发而私钥保密解决了密钥交换问题但是速度慢
摘要算法 数字签名
在计算机里使用摘要算法哈希函数来计算出内容的哈希值也就是内容的【指纹】这个哈希值是唯一的且无法通过哈希值推导出内容。
通过哈希算法可以确保内容不被篡改但是并不能保证【内容 哈希值】不会被中间人替换因为这里缺少对客户端收到的信息是否来源于服务端的证明。
为了避免这种情况计算机会采用非对称加密算法来解决
一个是公钥这个可以公开给所有人一个是私钥这个必须是本人管理不可泄漏
这两个密钥可以双向加解密的比如可以用公钥加密内容私钥解密也可以用私钥加密内容公钥加密内容。
流程不同意味着目的也不同
公钥加密私钥解密这个目的是为了保证内容传输的安全因为被公钥加密的内容其他人是无法解密的只有持有私钥的人才能解密出内容私钥加密公钥解密这个目的是为了保证消息不会被冒充因为私钥是不可被泄露的如果公钥能正常解密出私钥加密的内容就能证明这个消息是源于持有私钥身份的人发送的
一般我们不会用非对称加密来加密实际的传输内容因为非对称加密的计算比较耗费性能的。
所以非对称加密的用途主要是在于通过【私钥加密公钥解密】的方式来确认消息的身份我们常说的数字签名算法就是这种方式不过私钥加密的内容不是内容本身而是对内容的哈希值加密私钥由服务器保管然后服务器向客户端颁发对应的公钥。如果客户端收到的信息能被公钥解密就说明该信息是由服务器发送的。
数字证书
前面我们知道可以通过哈希算法来保证消息的完整性可以通过数字签名来保证消息的来源可靠性。但是还远远不够缺少了身份验证的环节万一公钥是伪造的呢
举个
拿请假的例子虽然你爸爸持有私钥老师通过是否能用公钥解密来确认这个请假条是不是来源你父亲的。
但是我们还可以自己伪造出一对公私钥啊
你找了个夜晚偷偷把老师桌面上和你爸爸配对的公钥换成了你的公钥那么下次你在请假的时候你继续模仿你爸爸的字迹写了个请假条然后用你的私钥做个了「数字签名」。
但是老师并不知道自己的公钥被你替换过了所以他还是按照往常一样用公钥解密由于这个公钥和你的私钥是配对的老师当然能用这个被替换的公钥解密出来并且确认了内容的完整性于是老师就会以为是你父亲写的请假条又允许你请假了。
好家伙为了一个请假真的是斗智斗勇。
后面你的老师和父亲发现了你伪造公私钥的事情后决定重新商量一个对策来应对你这个臭家伙。
正所谓魔高一丈道高一尺。
既然伪造公私钥那么随意所以你爸把他的公钥注册到警察局警察局用他们自己的私钥对你父亲的公钥做了个数字签名然后把你爸爸的「个人信息 公钥 数字签名」打包成一个数字证书也就是说这个数字证书包含你爸爸的公钥。
这样你爸爸如果因为家里确实有事要向老师帮你请假的时候不仅会用自己的私钥对内容进行签名还会把数字证书给到老师。
老师拿到了数字证书后首先会去警察局验证这个数字证书是否合法因为数字证书里有警察局的数字签名警察局要验证证书合法性的时候用自己的公钥解密如果能解密成功就说明这个数字证书是在警察局注册过的就认为该数字证书是合法的然后就会把数字证书里头的公钥你爸爸的给到老师。
由于通过警察局验证了数字证书是合法的那么就能证明这个公钥就是你父亲的于是老师就可以安心的用这个公钥解密出请假条如果能解密出就证明是你爸爸写的请假条。
正是通过了一个权威的机构来证明你爸爸的身份所以你的伪造公私钥这个小伎俩就没用了。
在计算机里这个权威的机构就是 CA数字证书认证机构将服务器公钥放在数字证书中只要证书是可信的公钥就是可信的。 5.3、HTTPS 是如何建立连接的
SSL/TLS 协议基本流程
客户端向服务器索要并验证服务器的公钥双方协商生产【会话密钥】双方采用【会话密钥】进行加密通信
........................
5.4、HTTPS 的应用数据是如何保证完整性的
TLS 在实现上分为握手协议和记录协议两层
TLS 握手协议就是我们前面所说的 TLS 四次握手的过程负责协商加密算法和生成对称密钥后续用此密钥来保护应用程序数据即HTTP 数据TLS 记录协议负责保护应用程序数据并验证其完整性和来源所以对 HTTP 数据加密是使用记录协议
具体过程如下
首先消息被分割成多个较短的片段然后分别对每个片段进行压缩接下来经过压缩的片段会被加上消息认证码MAC 值这个就是通过哈希算法生成的这是为了保证完整性并进行数据的认证。通过附加消息认证码的 MAC 值可以识别出篡改。与此同时为了防止重放攻击在计算消息认证码时还加上了片段的编码再接下来经过压缩的片段再加上消息认证码会一起通过对称密码进行加密最后上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数
记录协议完成后最终的报文数据将传递到传输控制协议TCP层进行传输
5.5、HTTPS 就一定安全可靠吗
如果有假基站起了转发全部信息的作用这样是不是假基站就获取到全部信息了从而造成数据泄露
这个场景就是客户端通过浏览器向服务端发起 HTTPS 请求时被【假基站】转发到了一个【中间人服务器】于是客户端是和【中间人服务器】完成了 TLS 握手然后这个【中间人服务器】再与真正的服务器完成 TLS 握手
具体过程如下
客户端向服务端发起 HTTPS 建立连接请求时然后被【假基站】转发到了一个【中间人服务器】接着中间人向服务端发起 HTTPS 建立连接请求此时客户端与中间人进行 TLS 握手中间人与服务端进行 TLS 握手在客户端与中间人进行 TLS 握手的过程中中间人会发送自己的公钥证书给客户端客户端验证证书真伪然后从证书中拿到公钥并生成一个随机数用公钥加密随机数发送给中间人中间人使用私钥进行解密得到随机数此时双方都有随机数然后通过算法生成对称加密密钥A后续客户端与中间人通信就用这个对称加密密钥来加密数据了。在中间人与服务端进行 TLS 握手过程中服务端会发送从 CA 机构签发的公钥证书给中间人从证书中拿到公钥生成一个随机数用公钥加密随机数发送给服务端服务端使用私钥解密得到随机数此时双方都有随机数然后通过算法生成对称加密密钥B后续中间人与服务端通信就用这个对称加密密钥来加密数据了后续的通信过程中中间人用对称加密密钥A解密客户端的 HTTPS 请求的数据然后用对称加密密钥B加密 HTTPS 请求后转发给服务端接着服务端发送 HTTPS 响应数据给中间人中间人用对称加密密钥B解密 HTTPS 响应数据然后再用对称加密密钥A加密后转发给客户端。
从客户端的角度看其实并不知道网络中存在中间人服务器这个角色。那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于中间人能够偷看浏览器与服务端之间的 HTTPS 请求与响应数据
但是这是有前提的前提是用户必须点击接受了中间人服务器的证书。
中间人服务器与客户端在 TLS 握手的过程中实际上发送了自己为造册证书给浏览器而这个伪造的证书是能被浏览器客户端识别出是非法的于是会提醒用户该证书存在问题。如果用户执意点击【继续浏览此网站】相当于接受了中间人伪造的证书那么后续整个 HTTPS 通信都能被中间人监听了。另外如果你的电脑中毒了被恶意导入了中间人的根证书那么在验证中间人的证书的时候由于你的操作系统信任了中间人的根证书那么等同于中间人的证书是合法的这种情况下浏览器是不会弹出任何存在问题的风险提示的。
5.6、为什么抓包工具能够截取 HTTPS 数据
很多抓包工具之所以可以明文看到 HTTPS 数据工作原理与中间人一致
对于 HTTPS 连接来说中间人要满足以下两点才能实现真正的明文代理
中间人作为客户端与真实服务端建立连接的这一步不会有问题因为服务端不会校验客户端的身份中间人作为服务端与真实客户端建立连接这里会有客户端信任服务端的问题也就是服务端必须有对应域名的私钥
中间人要拿到私钥只能通过如下方式
去网站服务端拿到私钥去 CA 处拿域名签发私钥自己签发证书切要被浏览器信任
很显然只能通过第三种取得中间人的身份使用抓包工具进行 HTTPS 抓包的时候需要在客户端安装 Fiddler 的根证书这里实际上起到认证中心CA的作用。抓包工具能够抓包的关键是客户端会往系统受信任的根证书列表中导入抓包工具生成的证书而这个证书会被浏览器信任也就是抓包工具自己创建了一个认证中心CA客户端拿着中间人签发的证书去中间人自己的 CA 去认证当然认为这个证书是有效的。
如何避免被中间人抓取信息呢
首先我们要保证自己电脑的安全不要被病毒侵入而且也不要点击任何证书非法的网站这样 HTTPS 数据就不会被中间人截取到了当然还可以通过 HTTPS 双向认证的方式来避免这种问题一般我们的 HTTPS 都是单向认证客户端只会验证了服务端的身份但是服务端不会验证客户端的身份如果服务端检测到了客户端是不可信任的服务端就拒绝通信客户端如果发现服务端也是不可信任的也终止通信。
六、HTTP/1.1、HTTP/2、HTTP/3 的演变
6.1、HTTP/1.1 相比 HTTP/1.0 提高了什么性能
HTTP/1.1 相比 HTTP/1.0 性能上的改进
使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销支持管道网络传输只要第一个请求发送出去了不必等其回来就可以发送第二个请求出去可以减少整体的响应时间 但 HTTP/1.1 还是有性能瓶颈的
请求 / 响应头部未经压缩就发送首部信息越多延迟越大。只能压缩 Body 的部分发送冗长的首部每次互相发送相同的首部造成的浪费越多服务器是按请求的顺序相应的如果服务器响应慢会招致客户端一直请求不到数据也就是队头阻塞没有请求优先级控制请求只能从客户端开始服务器只能被动响应
6.2、HTTP/2 的优化
HTTP/2 是基于 HTTPS 的所以 HTTP/2 的安全性也是由保证的
HTTP/2 相比 HTTP/1.1 性能上的优化
头部压缩如果你同时发出多个请求它们的头部是一样的或者类似的那么协议会帮你消除重复的部分这就是【HPACK】算法在客户端和服务器同时维护一张头信息表所有字段都会存入这个表生成一个索引号以后就不发送同样的字段了只发送索引号就能提高速度了
二进制格式不再像 HTTP/1.1 里的纯文本形式的报文而是全面采用了二进制格式头信息和数据体都是二进制并且统称为帧头信息帧和数据帧。虽然对人不太友好但是对计算机非常好收到报文之后无需再将明文的报文转化成二进制而是直接解析二进制报文这增加了数据的传输效率。
并发传输我们都知道 HTTP/1.1 是基于【请求-响应】模型的同一个连接中HTTP 完成一个事务才能处理下一个事务也就是说发出请求等待响应的过程中是没办法做其他事情的如果响应迟迟下不来那么后续的请求是无法被发送的也就造成了队头堵塞的问题。而 2.0 引入了 Stream 的概念。多个 Stream 复用在一条 TCP 连接上Stream 中可以包含多个 message 一个message 中包含多个 Frame Frame 是 2.0 的最小单位以二进制压缩格式存放HTTP/1 的内容。针对不同的 HTTP 请求用独一无二的 Stream ID 来区分接收端可以通过 Stream ID 有序组装成 HTTP 消息不同的 Stream 的帧是可以乱序发送的因此可以并发不同的 Stream 也就是 HTTP/2 可以并行交错发送请求和响应服务端收到后会根据相同的 Stream ID 有序组装成 HTTP 消息。 服务器主动推送资源服务器不再是被动地响应可以主动的向客户端发送消息客户端和服务端都可以发送建立 Stream Stream ID 号是有区别的客户端建立的 Stream 必须是奇数号而服务器建立的 Stream 必须是偶数号。比如客户端通过 请求从服务器获取到了 html 文件而 html文件还需要 css 文件渲染这时客户端还要再次发起获取 css 文件的请求需要消息往返两次如果是HTTP/2 服务器可以直接主动推送 css 文件减少了消息传递的次数。
6.3、HTTP/2 的缺陷
HTTP/2 是基于 TCP 协议来传输数据的TCP 是字节流协议TCP 层必须保证收到的字节数据是完整且连续的这样内核才会将缓冲区里的数据返回给 HTTP 应用那么当【前一个字节数据】没有到达时后收到的字节数据只能存放在内核缓冲区中只有等到这一个字节数据到达时HTTP/2 应用层才能从内核拿到数据这就是 HTTP/2 队头阻塞的问题。所以一旦出现了丢包现象就会触发 TCP 的重传机制这样在一个 TCP 连接中的所有 hTTP 请求都必须等待这个丢了的包被重传过来。
6.4、HTTP/3 做了哪些优化
HTTP/1.1 和 HTTP/2 都有队头阻塞的问题
HTTP/1.1 中的管道虽然解决了请求的队头阻塞但是没有解决响应的队头阻塞因为服务端需要按顺序响应收到的请求如果服务端处理某个请求消耗的时间比较长那么只能等待响应完这个请求后才能处理下一个请求这属于 HTTP 层队头阻塞。
HTTP/2 虽然通过多个请求复用一个 TCP 连接解决了 HTTP 的队头阻塞但是一旦发生丢包就会阻塞住所有的 HTTP 请求这属于 TCP 层队头阻塞。
HTTP/3 是如何解决的呢
HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP 协议
UDP 传输协议是不管发送顺序、丢包的所以不会出现像 HTTP/2 队头阻塞的问题。但基于 UDP 的 QUIC 协议可以实现类似 TCP 的可靠传输。
QUIC 的 3 特点
无队头阻塞当某个流发生丢包时只会阻塞这个流其他流不会受到影响因此不存在队头阻塞问题更快的连接建立虽然需要进行 QUIC 协议的握手但是这个握手仅需 1 RTT握手的目的是为了确认双方的【连接ID】连接迁移就是基于连接 ID 来实现的。在 3 中QUIC 内部包含了 TLS它在自己的帧会携带 TLS 的记录。再加上 QUIC 使用的是 TLS/1.3 因此仅需一个 RTT 就可以同时完成建立连接与密钥协商连接迁移基于 TCP 传输协议的 HTTP 协议由于是通过四元组源 IP源端口目的IP目的端口确定一条 TCP 的连接。那么当移动设备的网络从 4G 切换到 wifi 时。意味着 IP 地址也变化了那么就需要断开连接重新建立连接。而 QUIC 协议没有使用四元组来绑定连接而是通过连接 ID 来标记自己因此即使移动设备的网络变化之后导致 IP 地址变化了只要仍保有上下文信息就可以无缝复用原连接消除连接的成本达到了连接迁移的功能
七、HTTP/1.1 如何优化
从三个优化思路来优化 HTTP/1.1协议
尽量避免发送 HTTP 请求在需要发送 HTTP 请求时考虑如何减少请求次数减少服务器的 HTTP 响应的数据大小
7.1、避免发送 HTTP 请求
对于一些具有重复性的 HTTP 请求比如每次请求的数据都是相同的我们可以把这对【请求-响应】的数据都缓存在本地那么下次就直接读取本地的数据不必在通过网络获取服务器的响应。
7.2、如何减少 HTTP 请求次数
从这几个方面入手
减少重定向请求次数和并请求延迟发送请求
什么是重定向服务器上的一个资源可能由于迁移等原因从 url1 移至 url2 后客户端不知情还是继续请求 url1这是服务器不能暴力返回错误而是通过 302 响应码和 Location 头部告诉客户端该资源已经迁移至 url2 了于是客户端需要再发送 url2 请求以获得服务器的资源。
7.2.1、减少重定向次数
如果重定向请求越多那么客户端就要多次发起 HTTP 请求每一次的 HTTP 请求都得经过网络这无疑会降低网络性能。
另外服务端这一方往往不只有一台服务器比如源服务器上一级是代理服务器然后代理服务器与客户端通信这时客户端重定向就会导致客户端与代理服务器之间需要 2 次消息传递如果将重定向的工作交由代理服务器完成就能减少 HTTP 请求的次数啦 7.2.2、和并请求
把多个访问小文件的请求合并成一个大的请求虽然传输的总资源还是一样的但是减少请求也就意味着减少了重复发送的 HTTP 头部。
例如可以将多个小图片的请求合并成一个大图片来减少 HTTP 请求的次数从而减少网络的开销。合并请求的方式就是合并资源以一个大资源的请求替换多个小资源的请求。
但是这样会带来新的问题当大资源中的某一个小资源发生变化后客户端必须重新下载整个完整的大资源文件这显然会带来额外的网络消耗。
7.2.3、延迟发送请求
一般 HTML 里会含有很多 HTTP 的 URL 当前不需要的资源我们没必要获取过来于是可以通过按需获取的方式来减少第一时间的 HTTP 请求次数。
请求网页的时候没必要把全部的资源都获取到而是只获取当前用户所看到的页面资源当用户向下滑动的时候再向服务器获取接下来的资源这样就达到了延迟发送请求的效果。
7.3、如何减少 HTTP 响应的数据大小
对于 HTTP 的请求和响应通常 HTTP 的响应数据大小会比较大也就是服务器返回的资源会比较大。于是我们可以考虑对响应的资源进行压缩这样就可以减少响应的数据大小从而提高网络传输的效率。
八、HTTPS RSA 握手解析
传统的 TLS 握手基本都是使用 RSA 算法来实现密钥交换的在将 TLS 证书部署服务端时证书文件其实就是服务端的公钥会在 TLS 握手阶段传递给客户端而服务端的私钥则一直留在服务端一定要确保私钥不能被窃取。
在 RSA 密钥协商算法中客户端会生成随机密钥并使用服务端的公钥加密后再传给服务端。根据非对称算法公钥加密的消息仅能通过私钥解密这样服务端解密后双方就获取了相同的密钥再用它加密应用信息。
RSA 握手握手过程
TLS 第一次握手
客户端首先会发一个【Client Hello】消息这是跟服务器【打招呼】消息里面有客户端使用的 TLS 版本号支持的密码套件列表以及生成的【随机数Client Random】这个随机数会被服务端保留它是生成对称加密密码的材料之一。
TLS 第二次握手
当服务端收到客户端的【Client Hello】消息后会确认 TLS 版本号是否支持和从密码套件列表中选择一个密码套件以及生成随机数Server Random。
接着返回【Server Hello】消息消息里面有服务器确认的 TLS 版本号也给出了随机数Server Hello然后从客户端的密码套件列表选择了一个合适的密码套件。
密码套件形式基本是【密码交换算法 签名算法 对称加密算法 摘要算法】。
就前面这两个客户端和服务端相互【打招呼】的过程客户端和服务端就已经确认了 TLS 版本和使用的密码套件而且你可能发现客户端和服务端都会各自生成一个随机数并且还会把随机数传递给对方。这个随机数的作用就是为后续作为生成【会话密钥】的条件所谓的会话密钥就是数据传输时所使用的对称加密密钥。
然后服务端为了证明自己的身份就会发送【Server Certificate】给客户端这个消息里有数字证书随后服务端发了【Server Hello Done】消息目的是告诉客户端我已经把该给你的东西都给你了。
TLS 第三次握手
客户端验证完第二次握手发送来的证书之后认为可信则继续。
接着客户端会生成一个新的随机数pre-master用服务器的 RSA 公钥加密该随机数通过【Client Key Exchange】消息传递给服务端。
服务端收到后用 RSA 私钥解密得到客户端发来的随机数pre-master。
至此客户端和服务端双方都共享了三个随机数分别是 Client RandomServer Randompre-master。于是双方根据已经得到得三个随机数生成会话密钥Master Secret它是对称密钥用于后续的 HTTP 请求/响应的数据加解密.然后客户端再发送一个【Encrypted Handshake MessageFinshd】消息把之前所有发送的数据做个摘要再用会话密钥master secret加密一下让服务器做个验证验证加密通信是否可用和【之前握手信息是否有被中途篡改过】可以发现【Change Cipher Spec】之前传输的 TLS 握手数据都是明文之后都是对称加密密钥的密文。
TLS 第四次握手
服务器也是同样的操作发【Change Cipher Spec】和【Encrypted Handshake Message】消息如果双方都验证加密和解密没问题那么握手正式完成。最后就用【会话加密】加解密 HTTP 请求和响应了
RSA 算法的缺陷
使用 RSA 密钥协商算法的最大问题是不支持前置保密因为客户端传递随机数给服务端时使用的是公钥加密的服务端收到后会用私钥解密得到随机数。所以一旦服务端的私钥泄露了过去被第三方捕获的所有 TLS 通讯密文都会被破解
九、优化 HTTPS
硬件优化HTTPS 协议是计算密集型而不是 IO 密集型所以可以升级性能更好的 CPU 或者选择可以支持 AES-NI 特性的 CPU因为这款 CPU 在指令级别优化了 AES 算法加速了加解密时间。
密钥交换算法优化使用 RSA 密钥交换算法的 TLS 握手过程不仅慢而且安全性也不高如果可以尽量使用 ECDHE 密钥交换算法替换 RSA 算法。可以将 TLS 握手的消息往返由 2 RTT 减少到 1 RTT而且安全性高具备前向安全性
TLS 升级直接把 TLS 的版本升级大幅度减少握手的步骤完成 TLS 握手只要 1 RTT而且安全性更高
证书传递优化减少证书的大小可以节省带宽减少客户的运算量。对于服务器的证书应该选择椭圆曲线证书ECDSA证书而不是 RSA 证书因为在相同安全强度下ECC密钥长度比 RSA 要短得多
会话复用会话复用分为两种一种是 Session ID另外一种是 Session Ticket。
Session ID客户端与服务端首次 TLS 握手连接后双方会在内存缓存会话密钥用唯一的 Session ID 来标识再次连接时Hello 消息里就会带上 Session ID服务器收到后就会在内存中找如果找到就直接使用该会话密钥回复会话状态跳过其余的过程只用一个消息往返就可以建立安全通信。
缺点
服务器必须保持每一个客户端的会话密钥随着客户端的增多服务器的内存压力也会越来越大现在网站服务一般是由多台服务器通过负载均衡提供服务的客户端再次连接不一定会命中上次访问过的服务器于是还是要走完整的 TLS 握手过程
Session Ticket服务器不再缓存每个客户端的会话密钥而是把缓存的工作交给了客户端类似于 HTTP 中的 Cookie但是要注意的是需要对会话密钥设定一个合理的过期时间避免重放攻击。
重放攻击 假设 A 想向 B 证明自己的身份。B 要求 A 的密码作为身份证明A 应尽全力提供。与此同时 E 窃听了对话并保留了密码。
交换结束后E 冒充 A 连接到 B 当被要求提供身份证明时E 发送从 B 接受的最后一个会话中读取的 A 的密码从而授予 E 访问权限。
重放攻击的危险之处在于如果中间人截获了某个客户端的 Session ID 或 Session Ticket 以及 POST 报文而一般的 POST 请求会改变数据库的数据中间人就可以利用此截获的报文不断地向服务器发送该报文这样就会导致数据库的数据被中间人改变了而客户是不知情的。