基于HTTP应用程序的乐趣,but…
HTTP
1.HTTP基本概念
(1)超文本传输协议
HTTP是超文本传输协议(HyperText Transfer Protocol),准确的定义为HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
- 协议:HTTP确认了一种计算机之间交流通信规范,以及各种相关的各种控制和错误处理方式(行为约定和规范)
- 传输:HTTP是一个双向协议,传输就是数据需要经过一系列的物理介质从一个端系统传送到另外一个端系统的过程(请求方-应答方)
- 超文本:超文本顾名思义就是超越了普通文本的文本,最常用的超文本是HTML,是文章、图片、视频以及可以跳转到其他超文本等的混合体
(2)HTTP状态码
好像没毛病,更加具体的说明如下:
- 1xx:提示信息,是协议处理中的中间状态,实际用到比较少
- 2xx:服务器成功处理客户端的请求
- 200 (OK):最常见的成功状态码,表示一切正常,非HEAD请求,服务器返回的响应头都会有body数据
- 204(No Content):与200基本相同,但是响应头没有body数据
- 206(Partial Content):应用于HTTP分块下载或断电续传,表示响应返回的body数据并不是资源的全部
- 3xx:客户端请求的资源发生了变动,需要进行重定向(在响应头里使用字段
Location
,指明后续要跳转的 URL)- 301(Moved Permanently):表示永久重定向,说明请求的资源已经不存在,需要改用新的URL再次访问
- 302(Moved Permanently):表示临时重定向,说明请求的资源还在,但暂时需要用另一个URL来访问
- 304(Not Modified):缓冲重定向,用于缓存控制,表示资源未修改,重定向到已存在的缓冲文件
- 4xx:客户端发送的报文有误,服务器无法处理
- 400(Bad Request):表示客户端请求的报文有误,但是是个笼统的错误
- 403(Forbidden):表示服务器禁止访问资源,并不是客户端请求出错
- 404(Not Found):表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端
- 5xx:服务器处理时内部发生了错误
- 500(Internal Server Error):一个笼统通用的错误:是的,服务器发生错误了,我们也不到什么错误
- 501(Not Implemented):客户端请求的功能暂不支持(敬请期待)
- 502(Bad Gateway):服务器自身工作正常,访问后端服务器时发生了错误(通常时用作网关或代理时的错误码)
- 503(Service Unavailable):服务器当前正忙,暂时无法响应
(3)HTTP常见字段
通用标头:通用标头可以出现在请求标头和响应标头
Date:表示创建报文时间(格林威治标准时间)
Date: Wed, 21 Oct 2015 07:28:00 GMT
Cache-Control:可以表示可缓存性、阈值性、 重新验证并重新加载和其他特性
Cache-control: no-cache
Connection:决定当前事务(一次三次握手和四次挥手)完成后,是否关闭网络连接(即是否复用TCP连接)
Connection: keep-alive
:持久性连接,一次事务完成后不关闭网络连接Connection: close
:非持久化连接,一次事务完成后关闭网络连接
实体标头:实体标头是描述消息正文内容的 HTTP 标头
- Content-Length:指示实体主体的大小,以字节为单位,发送到接收方
- Content-Type:用于描述数据类型(格式),与Accept配套
Content-Encoding:用来说明描述的压缩方法和编码类型,与Accept-Encoding配套
- Content-Language:描述了客户端或者服务端能够接受的语言,与Accept-Language配套
请求标头:
Host:指明服务器域名与TCP端口号(也有写作authority)
Host: autovy.github.io
Referer:告诉服务器该网页是从哪个页面链接跳转过来的
Referer: https://autovy.github.io/
If-None-Match:使请求标头成为条件请求,当与给定资源ETag不匹配时才会处理请求
if-none-match: W/"61665f52-7ba7"
If-Modified-Since:If-Modified-Since 通常会与 If-None-Match 搭配使用,用于确认代理或客户端拥有的本地资源的有效性(在
Last-Modified
之后更新了服务器资源,那么服务器会响应 200,如果在Last-Modified
之后没有更新过资源,则返回 304)If-Modified-Since: Sat, 09 Oct 2021 01:58:35 GMT
Accept:告知服务器客户端能够理解的MIME类型,与Content-Type配套
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
- Accept-Charset:规定服务器处理表单数据所接受的字符集
Accept-Language :用来告知服务器客户端能够处理的自然语言集
accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
响应标头:
- Access-Control-Allow-Origin: 指定一个来源,它告诉浏览器允许该来源进行资源访问
Keep-Alive:表示的是 Connection 非持续连接的存活时间,可以进行指定,与Connection配套
- Server:服务器标头包含有关原始服务器用来处理请求的软件的信息
- Set-Cookie:用于服务器向客户端发送 sessionID
- Transfer-Encoding:规定了传输报文主体时采用的编码方式
- X-Frame-Options:用于控制网站内容在其他 Web 网站的 Frame 标签内的显示问题,其主要目的是为了防止点击劫持攻击
(4)HTTP无状态分析
无状态协议指浏览器对于事务的处理没有记忆能力,HTTP连接之间彼此独立,不会对请求和响应之间的通信进行保存
而Cookie技术可以通过在请求和响应报文中写入Cookie信息来控制客户端的状态
- 客户端第一次向服务端发起请求
- 服务端开辟一块Session空间,同时生成一个sessionId,通过响应头的Set-Cookie命令要求客户端设置Cookie
- 客户端收到响应后,在本地设置JSESSIONID的Cookie信息,默认过期时间为浏览器会话结束;接下来客户端向同一个完整发送请求时都会携带该Cookie信息
- 服务端通过读取请求头的Cookie信息,获取JSESSIONID的值,与存储的Session内的seesionId匹配
此外还有一种让浏览器有记忆能力的机制——JWT机制(JSON WEB TOKEN),与Cookie不同,JWT是保存在客户端的信息,广泛用于单点登录,这里先挖个坑以后会详细出一篇讲单点登录的文章
JWT是基于token的鉴权机制,不需要服务端去保留用户的认证信息或者会话信息
- 用户使用用户名密码来请求服务器
- 服务器进行验证用户的信息
- 服务器通过验证发送给用户一个token(令牌)
- 客户端存储token,并在每次请求时附送上这个token值
- 服务端验证token值,并返回数据(token一般存在数据库中,也可以放在内存中)
2.GET与POST
(1)GET与POST区别
GET请求报文:
1 | GET /home.html |
POST请求报文:
1 | POST / |
- GET方法的含义是从服务器获取资源,发送的内容添加在url后
- POST方法先URI指定资源提交数据,这些数据放在报文body中
(2)安全与幂等
安全:在HTTP协议中,安全即请求方法不全不会破坏服务器的资源
幂等:多次执行相同操作,结果相同即一次请求和重复的多次请求对系统资源的影响是一致的,幂等思想在开发中有多处应用,可参考文章幂等本质了解更多
GET: GET方法是安全且幂等的,它是只读操作,服务器上数据安全且每次结果相同
POST:POST方法是不安全且不幂等,它是新增或提交数据操作会修改服务器上的资源,所以不安全;多次提交数据就会创建多个资源,所以不是幂等的
3.HTTP特性
(1)HTTP的优点
- 简单:HTTP 基本的报文格式就是
header + body
,头部信息也是key-value
简单文本的形式,易于理解 - 灵活和易于扩展:HTTP协议中的各类请求方法、URI/URL、状态码、头字段等每个组成要求都允许开发人员自定义和扩充,并且HTTP工作在应用层,其下层可以随意变化
- 应用广泛和跨平台:HTTP的应用范围广泛,而且可以跨平台使用
(2)HTTP的缺点
无状态双刃剑
- 无状态的好处:服务器不需要记忆HTTP状态,不需要额外资源记录状态信息,减轻服务器负担
- 无状态的坏处:服务器在需要进行关联操作时会非常麻烦
- 无状态的问题可以配合Cookie或Token进行解决
明文传输双刃剑
- 明文传输好处:方便阅读,为调试提供极大的便利性
- 明文传输坏处:你能看到的信息别人也能看到,敏感信息直接就裸奔了
- 不安全
- 通信用明文,内容容易被窃听
- 不验证通信方的身份,可能遭遇伪装
- 无法验证报文的完整性,可以会被篡改
(3)HTTP性能
主要针对目前应用广泛的HTTP/1.1进行评测
长连接:提供持久连接,减少TCP连接的重复建立和断开所造成的额外开销
管道网络传输:客户端发起多个请求,发起了一个请求后不必等待响应,而是继续发送下一个请求,从而减少整体的响应时间
队头阻塞:当顺序发送时,请求序列中的一个请求被阻塞了,在后面排队的所有请求被阻塞了
4.HTTP版本比较
(1)HTTP/1.1
HTTP/1.1的性能改进:
- 使用长连接改善短链接造成的性能开销
- 支持管道网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间
HTTP/1.1 性能瓶颈:
- 请求/响应头部未经压缩就发送,只压缩了Body部分,首部信息越多延迟越大
- 发送冗长的首部,每次互相发送相同的首部造成浪费较多
- 队头阻塞
- 没有请求优先级控制
- 请求只能从客户端开始,服务器只能被动响应
(2)HTTP/2
HTTP/2的性能改进:
头部压缩
利用HPACK算法压缩头部,如果同时发出多个请求,可以消除重复的部分(在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号)
二进制格式
报文采用二进制格式而不是纯文本的形式,头信息和数据体都是二进制统称为帧,增加数据传输的效率
数据流
数据包不是按顺序发送,同一个连接里面连续的数据包,可能属于不同的回应
因此要对数据包做标记,每个请求或回应的所有数据包,称为一个数据流(
Stream
)每个数据流都标记着一个独一无二的编号,其中规定客户端发出的数据流编号为奇数, 服务器发出的数据流编号为偶数
客户端还可以指定数据流的优先级,优先级高的请求,服务器就先响应该请求
多路复用
在一个连接中并发多个请求或回应,而不用按照顺序一一对应,不需要排队等待,也就不会再出现「队头阻塞」问题,降低了延迟,大幅度提高了连接的利用率
服务器推送
服务不再是被动地响应,也可以主动向客户端发送消息
在浏览器刚请求 HTML 的时候,就提前把可能会用到的 JS、CSS 文件等静态资源主动发给客户端,减少延时的等待,也就是服务器推送
HTTP/2 性能瓶颈:
- 多个HTTP请求复用一个TCP连接,下层的 TCP 协议是不知道有多少个 HTTP 请求
- 一旦发生丢包现象,就会触发重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这个丢了的包被重传回来
- 这些都是基于TCP传输层的问题,所以 HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP
(3)HTTP/3
HTTP/3的性能改进:
HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP,UDP 发生是不管顺序,也不管丢包的,所以不会出现 HTTP/1.1 的队头阻塞 和 HTTP/2 的一个丢包全部重传问题
UDP是不可靠的传输,所以HTTP/3使用的是基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输
QUIC协议当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响
TL3 升级成了最新的
1.3
版本,头部压缩算法也升级成了QPack
HTTPS 要建立一个连接,要花费 6 次交互,先是建立三次握手,然后是
TLS/1.3
的三次握手。QUIC 直接把以往的 TCP 和TLS/1.3
的 6 次交互合并成了 3 次,减少了交互次数QUIC 是一个在 UDP 之上的伪 TCP + TLS + HTTP/2 的多路复用的协议
![img](https://raw.githubusercontent.com/Autovy/Image/master/img/202110162120028.jpeg)
HTTP/3 性能瓶颈:
QUIC 是新协议,对于很多网络设备,根本不知道什么是 QUIC,只会当做 UDP,普及的进度非常的缓慢
HTTPS
1.HTTPS基本概念
(1)HTTPS定义
HTTPS(HyperText Transfer Protocol Secure)超文本传输安全协议,数据通信仍然是HTTP,但利用SSL/TLS加密数据包
(2)HTTP的安全问题
HTTP的明文传输是一个致命缺陷,没有经过任何加密,而这些明文数据会经过WiFi、路由器、运营商、机房等多个物理设备节点,如果在这中间任意一个节点被监听,传输的内容就会完全暴露,,这一攻击手法叫做MITM(Man In The Middle)中间人攻击
2.HTTPS实现原理
(1)对称加密
对称加密算法使用同一个密钥进行加密和解密
- 优点:速度快,适合数据量比较大的数据进行加密
- 缺点:在HTTPS的传输场景下,服务端事先并不知道客户端是谁,必然需要一个密钥传输过程,这意味着该密钥必定会泄露,后续的加密就不起作用了
(2)非对称加密:一组公私钥
非对称加密需要两个密钥,一个公开密钥(Public Key),一个私有密钥(Private Key)。公钥和私钥是一对,如果使用公钥进行加密的数据,只有对应的私钥才能解密。相对的,如果是使用私钥加密的数据,只有对应的公钥才能解密
- 优点:当客户端发起连接请求,服务端将公钥传输过去,客户端利用公钥加密好信息,再将密文发送给服务端,服务端里用私钥解密,从而基本保证了客户端发送信息是安全的(只有服务器的私钥可解)
- 缺点:服务器无法返回加密安全的数据,服务器有公钥和私钥,客户端只有公钥。如果服务器用公钥加密,客户端也没有私钥可以解密;如果服务器用私钥加密,但是公钥相当于公开的,这样数据就不安全了
严格来说,私钥并不能用来加密,而一般用作签名使用,签名的功能也会应用在HTTPS中,后面再细嗦
(3)非对称加密:两组公私钥
一组公钥私钥只能保证客户端到服务端的单程加解密,理论上使用两组公钥私钥是可以保证往返加解密
- 服务端有非对称加密的公钥A1,私钥A2
- 客户端有非对称加密的公钥B1,私钥B2
- 客户端向服务端发起请求,服务端将公钥A1返回给客户端
- 浏览器收到公钥A1,将自己保存的公钥B1发送给服务端
- 之后浏览器所有向客户端发送的数据,使用公钥B1加密,客户端可以使用私钥B2解密
- 客户端所有向服务端发送的数据,使用公钥A1加密,服务端可以使用私钥A2解密
虽然非对称加密两组公私钥可以让两条传输方向都经过非对称加密,都能保证安全性,但是非对称加密耗时远大于对称加密,对性能有很大的损耗
(4)混合加密
混合加密是对称加密和非对称加密的结合体,即传输密钥时(一般传输共享的对称密钥)使用非对称加密的公钥加密,传输数据时使用共享对称密钥加密
- 非对称加密交换对称加密的会话密钥
- 对称加密使用会话密钥加密并交换数据
具体步骤如下:
- 服务端有非对称加密的公钥A1,私钥A2
- 客户端发起请求,服务端将公钥A1返回给客户端
- 客户端随机生成一个对称加密的密钥K,用公钥A1加密后发送给服务端
- 服务端收到密文后用自己的私钥A2解密,得到对称密钥K,此时完成了安全的对称密钥交换,解决了对称加密时密钥传输被人窃取的问题
- 之后双方通信都使用密钥K进行对称加解密
(5)CA与数字证书
混合加密兼顾了安全性,但是仍然无法保证安全,非对称加密的算法是公开的,所有人都可以生成一对公钥私钥,我们仍需要考虑中间人攻击
- 服务端返回公钥A1的过程中,中间人替换成自己准备好的的公钥B1传送给客户端
- 客户端对篡改行为一无所知,傻傻地使用公钥B1加密了对称加密使用的会话密钥K
- 中间人截获公钥B1加密的会话密钥K,利用自己的私钥B2简简单单解个密,会话密钥K就暴露了,再使用服务端的公钥A1加密K传送给服务端,成功欺骗服务端,完成了通信链路。此后的的通信数据和明文传输无异
这一问题的核心是:客户端无法确认收到的公钥是不是真的来源于服务端,无法保证公钥不被篡改和其信任度,这时就需要第三方权威机构CA(数字证书认证机构)将服务器公钥放在数字证书中,只要证书可信,公钥就可信
摘要算法(哈希处理)保证证书不被篡改的原理:
服务器的公钥要事先提交到CA进行注册,申请一份数字证书(数字证书包含证书持有者,证书有效期,服务器公钥,哈希算法等)
CA在颁发数字证书前对证书明文信息进行哈希处理(信息摘要计算),并对哈希值用CA的私钥处理得到数字签名对数字证书进行加签
CA的公钥会内置在浏览器或操作系统中,不需要额外的网络传输
客户端发送请求时,服务端通过发送数字证书传输服务器的公钥
客户端得到证书,分解为明文部分Text和数字签名Sig1,使用CA机构的公钥进行解签得到Sig2,用证书声明的哈希算法对明文部分Text进行哈希处理,再与Sig2对比,如果匹配成功表示证书可信即表示公钥可信
3.HTTPS工作流程
参考资料:(写的比我好😇)
HTTPS详解二:SSL / TLS 工作原理和详细握手过程
(1)HTTPS加解密流程
- 客户端发起HTTPS请求,默认使用服务器端的443端口进行连接
- 服务器收到请求,返回配好的包含公钥Pub的证书给客户端(对应的私钥Private保存在服务器不公开)
- 客户端收到证书,校验证书的合法性(包括证书的有效期,证书域名,请求域名,数字签名等),保证证书没有被篡改
- 客户端生成一个用于对称加密的随机key,并用证书内的公钥Pub进行解密,发送给服务端
- 服务端收到随机key的密文,使用公钥Pub对应的私钥Private解密得到客户端发送的随机key
- 服务端使用客户端发送的随机key对需要传输的HTTP数据进行对称加密,将密文返回客户端
- 客户端使用随机key对称解密密文,得到HTTP数据明文
- 后续的HTTPS传输数据都使用交换好的随机key进行对称加解密保证了数据的安全
(2)HTTPS通信流程图
HTTPS握手过程即TCP三次握手 + TLS握手
详细的TLS握手流程如下,其与HTTPS加解密的流程大致对应,但更侧重于TLS握手的概念
客户端发送clienthello消息:客户端发送clienthello消息发起握手请求,该消息包含了客户端支持的TLS版本号和密码组合以及一个client random随机字符串,需要约定的密码组合如下
- 握手期间所使用的的密钥交换和认证算法 (最常用的是 RSA 算法)
- 加密算法 (用于握手完成后的对称加密,常用的有 AES、3DES等)
- 信息摘要算法 (常用的有 SHA-256、SHA-1 和 MD5 等)
服务端发送serverhello消息:服务器发送serverhello消息对客户端进行回应,该消息包含数字证书,服务器选择的密码组合和server random随机字符串
客户端验证数字证书:客户端对服务器发来的证书进行验证,确保对方的合法身份
检查数字签名(前面有详细的讲解,数字签名即服务器对证书内容进行信息摘要计算后再用私钥加密的结果)
验证证书链(证书链也称为证书路径,用于认证实体合法身份的证书列表,可以验证服务器的合法身份,也可以保证根证书的安全)
检查证书的有效期
检查证书的撤回状态 (撤回代表证书已失效)
客户端发送premaster secret字符串密文:客户端生成随机字符串premaster secret(预主密钥),并用公钥进行加密发送给服务器,只有服务器的私钥可以解开
服务器解密premaster secret:服务器使用私钥解密premaster secret字符串
客户端服务端生成共享密钥:客户端和服务器均使用 client random,server random 和 premaster secret,并通过相同的算法生成相同的共享密钥 KEY
客户端就绪:客户端发送经过共享密钥KEY加密过的finished信号
服务端就绪:服务端发送经过共享密钥KEY加密过的finished信号
达成安全通信:握手完成,双方使用共享密钥KEY对称加密进行安全通信
HTTP 与 HTTPS对比
1.HTTPS与HTTP基本区别
- HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输
- HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输
- HTTP 的端口号是 80,HTTPS 的端口号是 443
- HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的
2.HTTP与HTTPS网络模型
(1)OSI 七层网络模型
(2)TCP/IP五层网络模型
TCP/IP网络模型着眼于传输过程,于是将应用层,表示层,会话层视为应用层
也有分为四层的TCP/IP网络模型,将数据链路层和物理层都表示为网络接口层
(3)OSI七层模型与TCP/IP五层模型对比
各层设备:
各层协议:
(4)HTTP与HTTPS网络模型
3.HTTPS相比HTTP的升级
(1)HTTP的安全风险
HTTP 由于是明文传输,所以安全上存在以下三个风险:
- 窃听风险,比如通信链路上可以获取通信内容
- 篡改风险,比如强制入垃圾广告,视觉污染
- 冒充风险,比如一些仿真的钓鱼网站
(2)HTTPS解决方案
- 混合加密的方式实现信息的机密性,解决了窃听的风险
- 摘要算法的方式来实现完整性,它能够为数据生成独一无二的「指纹」,指纹用于校验数据的完整性,解决了篡改的风险
- 将服务器公钥放入到数字证书中,解决了冒充的风险
��字证书**中,解决了冒充的风险