20211114 HTTP 协议入门
网络分层
网络传输需要处理的问题
在两台主机间进行网络请求需要处理的问题:
网络分层协议
解决方法:将网络分层,在不同分层中处理不同问题,在层级间通过定义标准化接口进行调用
为了简化网络的复杂度,网络通信的不同方面被分解为多层次结构,每一层只与紧挨着的上层或者下层进行交互,将网络分层,这样就可以修改,甚至替换某一层的软件,只要层与层之间的接口保持不变,就不会影响到其他层
- OSI( Open System Interconnection Reference Model ):开放系统互联参考模型
- TCP/IP 协议族
网络请求的分层解析流程
HTTP 协议
超文本传输协议 ( Hyper Text Transfer Protocol , HTTP ):一种无状态的,以请求/应答方式运行的协议,它使用可扩展的语义和自描述消息格式,与基于网络的超文本信息系统灵活的互动
HTTP 报文格式
HTTP 协议的 请求报文 和 响应报文 的结构基本相同,由三大部分组成:
- 起始行( start line ):描述请求或响应的基本信息
- 头部字段集合( header ):使用 key-value 形式更详细地说明报文
- 消息正文( entity ):实际传输的数据,它不一定是纯文本,可以是图片、视频等二进制数据
请求行报文格式
- 请求方法:如 GET/HEAD/PUT/POST ,表示对资源的操作
- 请求目标:通常是一个 URI ,标记了请求方法要操作的资源
- 版本号:表示报文使用的 HTTP 协议版本。
响应行报文格式
- 版本号:表示报文使用的 HTTP 协议版本
- 状态码:一个三位数,用代码的形式表示处理的结果,比如 200 是成功, 500 是服务器错误
- 原因:作为数字状态码补充,是更详细的解释文字,帮助人理解原因
HTTP 头字段
头部字段是 key-value 的形式, key 和 value 之间用 :
分隔,最后用 CRLF 换行表示字段结束。比如前后端分离时经常遇到的要与后端协商传输数据的类型 Content-type:application/json
,这里 key 就是 Content-type
, value 就是 application/json
。 HTTP 头字段非常灵活,不仅可以使用标准里的 Host
、 Connection
等已有头,也可以任意添加自定义头,这就给 HTTP 协议带来了无限的扩展可能。
头字段使用注意事项:
- 字段名不区分大小写,字段名里不允许岀现空格,可以使用连字符
-
,但不能使用下划线_
(有的服务器不会解析带下划线_
的头字段) - 字段名后面必须紧接着
:
,不能有空格,而:
后的字段值前可以有多个空格 - 字段的顺序是没有意义的,可以任意排列不影响语义
- 字段原则上不能重复,除非这个字段本身的语义允许,例如
Set-Cookie
常用头字段
HTTP 协议中有非常多的头字段,但基本上可以按照以下分类:
- 请求字段:请求头中的头字段;如
Host
,Referer
- 响应字段:响应头中的头字段,如:
Server
,Date
- 通用字段:在请求头和响应头里都可以出现,如
Content-type
,Connection
HTTP 请求的完整过程
当用户在浏览器输入网址回车之后,网络协议都做了哪些工作呢?
- 首先干活的是浏览器应用程序,他要解析出 URL 中的域名
- 根据域名获取对应的 IP 地址,首先从浏览器缓存中查看,如下可以查看浏览器中域名对应 IP 的解析
chrome://net-internals/#events
,如果没有则从本机域名解析文件 hosts (/etc/hosts
)中查看,还没有则从 LDNS( Local dns server )、 Root server 域名服务器、国际顶级域名服务商的 DNS 的层层解析 - 拿到 IP 地址后,浏览器就可以发起与服务器的三次握手
- 握手建立之后,就开始组装 http 请求报文,发送报文
- 服务器收到请求报文之后开始,请求报文解析,生成响应数据,发送响应数据
- 浏览器收到响应之后,开始渲染页面
TCP 协议
TCP ( Transmission Control Protocol ):面向连接的,可靠的,基于字节流的传输层通信协议
特点:
- 基于连接的:数据传输之前需要建立连接
- 全双工的:双向传输
- 字节流:不限制数据大小,打包成报文段,保证有序接收,重复报文自动丢弃
- 流量缓冲:解决双方处理能力的不匹配
- 可靠的传输服务:保证可达,丢包时通过重发机制实现可靠性
- 拥塞控制:防止网络出现恶性拥塞
TCP 报文结构
TCP 连接管理
- TCP 连接:四元组 (源地址,源端口,目的地址,目的端口)
- 确立连接: TCP 三次握手
- 同步通信双方初始序列号( ISN , initial sequence number )
- 协商 TCP 通信参数( MSS ,窗口信息,指定校验和算法 )
如何进行握手?
握手时内核发生了什么?
TCP 四次挥手
- A :发送 FIN 数据包,代表 A 不再发送数据
- B :收到请求,开始应答,避免了 A 重新发送 FIN 重试(应答机制)
- B :处理完数据之后关闭,关闭连接,以及发送 FIN 请求
- A :收到请求后发送 ACK 应答, B 服务可以释放连接
等待 2MSL 后释放连接
- 防止报文丢失,导致 B 重复发送 FIN
- 防止滞留在网络中的报文,对新建立的连接造成数据扰乱
字节流的协议
TCP 把应用交付的数据仅仅看成时一连串的无结构的字节流, TCP 并不知道字节流的含义, TCP 并不关心应用程序一次将多大的报文发送到 TCP 的缓存中,而是根据对方给出的窗口值和当前网络拥堵的程度来决定一个报文段应该包含多少个字节。
MSS : Max Segment Size ,默认 536 byte 实际数据
数据可靠性传输
停止等待协议
停止等待就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
重传机制
-
ack 报文丢失
-
请求报文丢失
滑动
窗口协议与累计确认(延时 ACK )
滑动窗口大小通过 TCP 三次握手和对端协商,且受网络状况影响
HTTPS 协议
HTTPS
由于 HTTP 天生 “明文” 的特点,整个传输过程完全透明,任何人都能够在链路中截获、修改或者伪造请求/响应报文,数据不具有可信性。因此就诞生了为安全而生的 HTTPS 协议。
使用 HTTPS 时,所有的 HTTP 请求和响应在发送到网络之前,都要进行加密
SSL/TLS
SSL 即安全套接层( Secure Sockets Layer ),由网景公司于 1994 年发明, IETF 在 1999 年把它改名为 TLS (传输层安全, Transport Layer Security )正式标准化,到今天 TLS 已经发展出了主流的三个版本,分别是 2006 年的 1.1 、 2008 年的 1.2 , 2018 的 1.3 ,每个新版本都紧跟密码学的发展和互联网的现状,持续强化安全和性能,已经成为了信息安全领域中的权威标准。
摘要算法
摘要算法能够把仼意长度的数据 “压缩” 成固定长度、而且独一无二的 “摘要” 字符串,就好像是给这段数据生成了一个数字 “指纹” 。任意微小的数据差异,都可以生成完全不同的摘要。所以可以通过把明文信息的摘要和明文一起加密进行传输,数据传输到对方之后再进行解密,重新对数据进行摘要,再比对就能发现数据有没有被篡改。这样就保证了数据的完整性。
加密算法
- 对称密钥加密算法 :编、解码使用相同密钥的算法,如( AES ,RC4 , ChaCha20 )
- 非对称密钥加密算法 :它有两个密钥,一个叫 公钥 ,一个叫 私钥 。两个密钥是不同的,公钥可以公开给任何人使用,而私钥必须严格保密。非对称加密可以解决 ”密钥交换“ 的问题。网站秘密保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。而黑客因为没有私钥,所以就无法破解密文。非对称密钥加密系统通常需要大量的数学运算,比较慢。如( DH 、 DSA 、 RSA 、 ECC )
TLS 里使用的混合加密方式,即把对称加密和非对称加密结合起来呢,两者互相取长补短,即能髙效地加密解密,又能安全地密钥交换。大致流程如下
-
通信开始的时候使用非对称算法如 RSA ,ECDHE 先解决密钥交换的问题
-
用随机数产生对称算法使用的 "会话密钥",再用公钥加密。会话密钥很短,所以即便使用非对称加密算法也可以很快完成加解密
-
对方拿到密文后用私钥解密,取出会话密钥。完成对称密钥的安全交换,后续就使用对称算法发完成数据交换
身份验证
数字证书组成:CA 信息,公钥用户信息,公钥,权威机构的签名,有效期
数字证书作用:
- 通过数字证书向浏览器证明身份
- 数字证书里面包含了公钥
数字证书的申请和验证
如何申请:
- 生成自己的公钥和私钥,服务器自己保留私钥
- 向 CA 机构提交公钥,公司,域名信息等待认证
- CA 机构通过线上,线下多种途径验证你提交信息的真实性,合法性
- 信息审核通过, CA 机构则会向你签发认证的数字证书,包含了公钥,组织信息, CA 信息,有效时间,证书序列号,同时生成一个签名
签名步骤: hash(你用于申请证书所提交的明文信息)=信息摘要; CA 再使用私钥对信息摘要进行加密,密文就是证书的数字签名
浏览器如何验证:
有了 CA 签名过的数字证书,当浏览器访问服务器时,服务器会返回数字证书给浏览器。浏览器收到证书后会对数字证书进行验证。
首先浏览器读取证书中相关的明文信息,采用 CA 签名时相同的 hash 函数计算得到信息摘要 A ,再利用对应的 CA 公钥解密数字签名数据得到信息摘要 B ,如果摘要 A 和摘要 B 一致,则可以确认证书时合法的