HTTP协议知识体系核心重点梳理
- TCP/IP协议
- 1.四层模型
- 2.通信过程
- 3.tcp三次握手和四次挥手
- 4.tcp安全传输
- 4. 一次HTTP通信流程
- HTTP协议
- HTTP/1.1
- Cookie
- Http报文格式
- 内容编码
- 分块传输编码
- HTTP状态码
- 重定向状态码
- 常用的通用首部
- cache-control
- Expires
- Connection
- Transfer-Encoding
- 常用的请求首部
- Accept开头的
- Authorization
- User-Agent
- 常用响应首部
- Location
- 实体首部字段
- Allow
- Content-Encoding
- Content-Length
- Content-MD5
- Content-Type
- Expires
- Last-Modified
- Https
- 使用Http通信具有哪些风险
- https协议是什么
- 对称加密和非对称加密在Https中使用的困境
- https所采用的混合加密机制
- 客户端如何证明自己获取的公钥就是对应服务器颁发的呢?
- 客户端通过证书验证公钥的合法性
- 如何防止CA颁发的证书被篡改
- 数字签名防止证书被篡改
- Https完整流程
- 参考
TCP/IP协议
1.四层模型
1.应用层: 规定应用程序之间的通信格式,应用层常见协议有: HTTP,HTTPS,FTP,DNS等协议。
2.传输层: 负责提供两台计算机之间的数据传输服务,运输层主要使用下面两种协议
- 传输控制协议TCP: 面向连接的,面向字节流的,可靠的数据传输服务。
- 用户数据报协议UDP:面向无连接的,不可靠的传输协议。
3.网络层: 负责选择合适的路由,将分组通过路由传递到目的主机,网络层主要使用的协议有:
- IP协议
- ARP协议: 负责根据ip地址找到对应主机的mac地址,用户将IP数据报交付给当前局域网内某台主机。方式: 通过主机和路由器缓存的arp表+广播的形式完成寻找。
- ICMP,BGP,OSPF,NAT等。
4.网络接口层(数据链路层,物理层):
- 数据链路层: 将网络层传递下来的IP数据报封装成帧,在相邻两个链路上进行传输。
- 物理层: 实现相邻两个计算机节点之间的比特流透明传输。
2.通信过程
3.tcp三次握手和四次挥手
TCP三次握手和四次挥手
4.tcp安全传输
- 基于数据块传输,数据块也被称为报文段或者段
- 给每个报文段分配一个序列号,用于对失序数据包进行排序和去重
- 数据报首部包含数据校验和,用来检验数据报是否出现差错
- 如果指定时间内没有收到目的端对某个报文段的确认信息,发送端会进行重传
- 通过发送端的发送窗口和接受端的接收窗口来进行动态流量控制
- 通过维护一个拥塞窗口来进行拥塞控制
- ARQ自动重传协议: 停止等待ARQ和连续ARQ协议。
TCP 传输可靠性保障
4. 一次HTTP通信流程
发送端:
- 通过DNS服务器完成域名到ip的地址的解析
- 按照HTTP协议封装好需要发送的http请求报文
- 传输层采用TCP协议,将应用层http报文切分成多个小的TCP报文段并赋予序号进行发送
- 网络层采用IP协议,选择合适的路由,同时利用ARP协议获得下一跳的目的主机的mac地址
接收端:
- 传输层采用TCP协议确保TCP报文段的按序达到,并将按序达到的TCP报文段拼接成完成的请求报文,同时剥去TCP首部,交给应用层处理
- 服务器获取到完整的HTTP数据报,按照HTTP协议解析,获取用户请求的资源地址,将资源采用同样的流程响应给客户端
HTTP协议
HTTP/1.1
- 持久连接: HTTP/1.1默认开启,部分HTTP/1.0支持,通过在请求头中添加keep-alive: true告知服务器本次http请求开启持久连接
好处:
- 复用了一次TCP连接,提高了http请求和响应的速度,减少了因为三次握手和四次挥手带来的网络开销。
- pipeline管道: http/1.1支持一次性批量发送多个http请求
Cookie
http协议本身是无状态的,在某些场景下我们需要记录客户端的状态,那么可以采用cookie-session技术来完成。
浏览器根据服务器响应报文中的Set-Cookie首部字段信息,获取服务器生成的cookie,并保存在浏览器中。
当下次通过浏览器请求对应服务器时,浏览器便会自动在请求报文中加入Cookie值后发送出去。
服务器可以从请求报文中的Cookie首部字段获取cookie值,然后根据cookie寻找session,session中保存了用户状态信息。
Http报文格式
下图展示了http请求报文和响应报文格式:
HTTP报文=报文首部+报文主体。(报文主体不一定存在)
内容编码
- 对报文实体内容进行压缩,减少本次数据传输量,常用的内容编码有: gzip,compress,deflate(zlib),identity(不进行编码)
分块传输编码
- 传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面,这种把主体分块的功能称为分块传输编码
每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。下面是一个例子。
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
HTTP状态码
1xx : 接收的请求正在处理
2xx : 请求正常处理完毕
3xx : 重定向状态码
4xx : 客户端错误状态码
5xx : 服务器错误状态码
重定向状态码
301 : 永久重定向 , 浏览器会缓存本次301重定向, 并忽略后续其他重定向
302: 临时重定向,浏览器不会进行缓存,每次请求需要从服务器获取本次重定向地址
303: 和302类似,不过303状态码表示重定向将采用GET方法获取资源,这一点与302状态码有区别
搞懂 HTTP 重定向 - 如何优雅地使用 301 - 腾讯云开发者社区-腾讯云 (tencent.com)
常用的通用首部
通用首部: 请求和响应都会使用的首部
cache-control
作用: 缓存控制
Cache-Control: private,max-age=0,no-cache
常用指令:
- no-store: 请求或响应包含机密内容,不能在本地存储请求或者响应的任何一个部分
- no-cache
- max-age: 缓存过期时间,设置为0,表示禁用缓存
Expires
Http/1.1版本缓存服务器在遇到同样存在Expires首部字段和max-age指令时,会优先处理max-age指令。
Http/1.0版本的缓存服务器则相反。
Connection
管理持久连接:
#关闭持久连接
Connection: close
#开启持久连接
Connection: keep-Alive
Http/1.1默认为持久连接。 旧版本的HTTP协议上如果想要开启持久连接,需要指定Connection首部字段的值为: Keep-Alive
Transfer-Encoding
规定传输报文主体时采用的编码方式,Http/1.1的传输编码方式仅对分块传输编码有效。
Transfer-Encoding: chunked
常用的请求首部
Accept开头的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-36i6mWQH-1677053800480)(C:/Users/zdh/AppData/Roaming/Typora/typora-user-images/image-20230222155053001.png)]
- accept: 指定客户端能够处理的媒体类型
- accept-charset: 能处理的字符集
- accept-encoding: 能处理的内容编码
- accept-language: 能处理的语言集
Authorization
- 当服务器需要客户端认证才能访问资源时,会响应一个401状态码
- 客户端此时在请求头中添加Authorization首部,并将对应的令牌作为值放入其中
User-Agent
将创建请求的浏览器和用户代理名称等信息传送给服务器:
常用响应首部
Location
将响应接收方引导到某个与请求URI位置不同的资源。
通常配合3xx请求重定向使用。
实体首部字段
Allow
Allow Get,Post
当服务器收到不支持的HTTP方法时,会以状态码405作为响应返回,同时把能支持的HTTP方法写入首部字段Allow后返回。
Content-Encoding
Content-Encoding: gzip
服务器告知客户端本次响应催实体的主体部分选用的内容编码方式。
Content-Length
Content-Length: 15000
表明了实体主体部分的大小。
Content-MD5
检查报文主体在传输过程中是否保持完整,以及确认传输到达。
Content-Type
指明实体主体内对象的媒体类型,和首部Accept一样,字段值用type/subtype形式赋值。
charset指明字符集。
Content-type: text/html;charset=UTF-8
Expires
指明响应资源的过期时间。
Last-Modified
资源最终修改时间。
Https
使用Http通信具有哪些风险
- 通信使用明文,内容可能会被监听
- 不验证通信方身份,因此由可能遭遇伪装
- 无法证明报文完整性,可能会遭到中间人攻击,从而篡改了请求和响应报文中的内容
https协议是什么
https并非一种新的协议,只是HTTP通信接口部分用SSL和TLS协议替代而已。
通常HTTP直接和TCP通信,当使用SSL时,则演变为先和SSL通信,再由SSL和TCP通信了。
简单来说,Https就是身披SSL协议这层外壳的HTTP。
在采用SSL后,HTTP就拥有了HTTPS的加密,证书和完整性保护这些功能。
SSL协议是独立与HTTP的协议,所以不光HTTP协议,其他运行在应用层的SMTP和Telnet等协议均可配合SSL协议使用。
对称加密和非对称加密在Https中使用的困境
-
对称加密: 加密和解密使用同一把秘钥。
困境: 发送秘钥就有被窃听的分析,但是不发送,对方就不能解密。 -
非对称加密: 一把公钥,一把私钥。公钥用来加密,但是不能解密。私钥用来解密。
困境: 非对称性加密涉及较为复杂的计算,如果https通信时采用非对称加密方式,那么通信效率就会很低。
https所采用的混合加密机制
Https在交换对称加密秘钥环节使用非对称性加密的方式,之后的通信过程中采用对称加密方式。
客户端如何证明自己获取的公钥就是对应服务器颁发的呢?
非对称性加密存在的问题在于,在服务器将公钥通过网络通道传送给客户端的这个过程中,可能会被攻击者劫持,并向客户端发送一个伪造的公钥,从而客户端将会使用该伪造公钥对数据进行加密,并在公开信道中传输。 同样攻击者会捕获这些加密数据包,并使用自己的私钥进行解密,而服务器确无法识别客户端发送的内容。
客户端通过证书验证公钥的合法性
问题的关键在于服务器不能直接将公钥公开在网络信道中传输,如果要对公钥再进行加密,就进入了鸡生蛋,蛋生鸡的问题。
所以,我们不直接将服务器的公钥传递给客户端,而是权威第三方机构使用它的私钥对我们的公钥进行加密,再传给客户端。客户端使用本地浏览器保存的第三方机构的公钥进行解密。
客户端不能通过网络去向CA要公钥,因为这个过程存在被拦截掉包可能。现实中,浏览器和操作系统都会维护一个权威的第三方机构列表(包括它们的公钥)。因为客户端接收到的证书中会写有颁发机构,客户端就根据这个颁发机构的值在本地找相应的公钥。
- 服务器提前向CA申请一个数字证书,同时服务器需要告诉CA自己的公钥。
- CA使用秘钥对服务器的公钥进行加密,然后生成一个证书,返回给服务器保存
- 服务器保存证书到本地
- 客户端发起请求获取公钥时,服务器返回给客户端对应的证书
- 客户端根据证书所属的第三方认证机构,从本地取出对应CA的公钥对证书进行解密
- 如果解密成功,说明证书合法,然后得到证书中保存的服务器公钥
如何防止CA颁发的证书被篡改
如果CA同时给多家公司颁发证书,并且对外暴露的是统一的公钥来解密这些证书,那么如果中间人也像CA申请了一份证书;
那么中间人就可以利用它申请到的证书替换服务器发送给客户端的证书,因为客户端通过公钥可以成功解密出中间人的证书,从而中间人又可以拦截用户请求并用自己的私钥解密客户端发送的消息了。
所以,根本原因在于客户端无法通过第三方机构的公钥区分证书具体是中间人的还是服务器的,只能区分当前证书是否合法。
数字签名防止证书被篡改
现在的问题在于我们需要证明证书不仅是由对应的CA机构颁发的,还必须是对应我们请求服务器所拥有的证书,而不是第三方中间人拥有的合法证书。
解决这个问题的唯一方案是验证证书的域名是否和要访问的域名一致。
摘要算法:一般用哈希函数来实现,可以理解成一种定长的压缩算法,它能把任意长度的数据压缩到固定长度。这好比是给数据加了一把锁,对数据有任何微小的改动都会使摘要变得截然不同。
- 服务器提前向CA申请证书,申请时,会告知CA自己的公钥,域名等信息,这些信息是放在一个CSR证书请求文件中的。
- CA验证信息是否正确,如果正确,则会生成一个证书,并使用私钥对证书进行数字签名,然后将签名放在证书内一起发送给服务器。
- 客户端发起请求时,在SSL握手阶段,会收到服务器的证书,客户端使用CA的公钥进行解密,取出证书中的数据,数字签名和服务器公钥。
- 如果解密成功,说明证书是合法的。
- 接着客户端再对数据进行Hash运算,将结果与数字签名做对比,如果一致则可以证明该证书就是属于对应服务器的。
数字签名在进行hash运算时,肯定包含了: 服务器公钥,服务器域名等信息。
客户端对数据进行Hash运算时,这里数据页肯定包含了: 服务器公钥,客户端所请求的服务器域名等信息。
如果如果以上两个计算出来的结果一致,则可以证明证书属于对应的服务器。
Https完整流程
1)用户在浏览器发起HTTPS请求,默认使用服务端的443端口进行连接;
2)HTTPS需要使用一套CA 数字证书,证书内会附带一个服务器的公钥Pub,而与之对应的私钥Private保留在服务端不公开;
3)服务端收到请求,返回配置好的包含公钥Pub的证书给客户端;
4)客户端收到证书,校验合法性,主要包括是否在有效期内、证书的域名与请求的域名是否匹配,上一级证书是否有效(递归判断,直到判断到系统内置或浏览器配置好的根证书),如果不通过,则显示HTTPS警告信息,如果通过则继续;
5)客户端生成一个用于对称加密的随机Key,并用证书内的公钥Pub进行加密,发送给服务端;
6)服务端收到随机Key的密文,使用与公钥Pub配对的私钥Private进行解密,得到客户端真正想发送的随机Key;
7)服务端使用客户端发送过来的随机Key对要传输的HTTP数据进行对称加密,将密文返回客户端;
8)客户端使用随机Key对称解密密文,得到HTTP数据明文;
9)后续HTTPS请求使用之前交换好的随机Key进行对称加解密。
参考
图解HTTP
为什么要用HTTPS?深入浅出,探密短连接的安全性
网络编程之如果这样来理解HTTPS,一篇就够了
网络编程之一文读懂HTTP协议的历史演变和设计思路