TCP 3次握手
TCP的几个关键标志位
位码即tcp标志位,有6种标示:
-
SYN(synchronous建立联机)
-
ACK(acknowledgement 确认)
-
PSH(push传送)
-
FIN(finish结束)
-
RST(reset重置)
-
URG(urgent紧急)
-
Sequence number(顺序号码)
-
Acknowledge number(确认号码)
-
主机A发送位码为syn=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;
-
主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),syn=1,ack=1,随机产生seq=7654321的包,此时服务器进入SYN_RECV状态
-
主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ack=1,主机B收到后确认seq值与ack=1则连接建立成功,客户端和服务器进入ESTABLISHED状态,完成三次握手。
- 握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
三次握手的原因
第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。
三次握手(A three way handshake)是必须的, 因为 sequence numbers(序列号)没有绑定到整个网络的全局时钟(全部统一使用一个时钟,就可以确定这个包是不是延迟到的)以及 TCP 可能有不同的机制来选择 ISN(初始序列号)。接收方接收到第一个 SYN 时,没有办法知道这个 SYN 是是否延迟了很久了,除非他有办法记住在这条连接中,最后接收到的那个sequence numbers(然而这不总是可行的)。这句话的意思是:一个 seq 过来了,跟现在记住的 seq 不一样,我怎么知道他是上条延迟的,还是上上条延迟的呢?所以,接收方一定需要跟发送方确认 SYN。
第二种解释:客户端发送的连接请求如果在网络中滞留,那么就会隔很长一段时间才能收到服务器端发回的连接确认。客户端等待一个超时重传时间之后,就会重新请求连接。但是这个滞留的连接请求最后还是会到达服务器,如果不进行三次握手,那么服务器就会打开两个连接。如果有第三次握手,客户端会忽略服务器之后发送的对滞留连接请求的连接确认,不进行第三次握手,因此就不会再次打开连接。
TCP 四次挥手
-
主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了
-
主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求,表示主机2也没有数据要发送给主机1了
-
主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态
-
主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
四次挥手的原因
TCP是全双工模式,这就意味着: 1.当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;但是,这个时候主机1还是可以接受来自主机2的数据; 2、当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的; 3、当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了, 4、之后彼此就会愉快的中断这次TCP连接
客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。
TIME_WAIT
客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:
- 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
- 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。
http1.0与http1.1
1、缓存处理:1.1添加更多的缓存控制策略(如:Entity tag,If-Match) 2、网络连接的优化:1.1支持断点续传 3、错误状态码的增多:1.1新增了24个错误状态响应码,丰富的错误码更加明确各个状态 4、Host头处理:支持Host头域,不在以IP为请求方标志 5、长连接:减少了建立和关闭连接的消耗和延迟。
http2.0
主要是增加了:二进制分帧和多路复用
- 二进制分帧层
帧是数据传输的最小单位,以二进制传输代替原本的明文传输,原本的报文消息被划分为更小的数据帧
1.0依然使用基于文本格式
- 多路复用
在一个 TCP 连接上,我们可以向对方不断发送帧,每帧的 stream identifier 标明这一帧属于哪个流,然后在对方接收时,根据 stream identifier 拼接每个流的所有帧组成一整块数据。 把 HTTP/1.1 每个请求都当作一个流,那么多个请求变成多个流,请求响应数据分成多个帧,不同流中的帧交错地发送给对方,这就是 HTTP/2 中的多路复用。流的概念实现了单连接上多请求 - 响应并行,解决了队头阻塞的问题,减少了 TCP 连接数量和 TCP 连接慢启动造成的问题.http2 对于同一域名只需要创建一个连接,而不是像 http/1.1 那样创建 6~8 个连接。
- 服务端推送
浏览器发送一个请求,服务器主动向浏览器推送与这个请求相关的资源,这样浏览器就不用发起后续请求。
- Header 压缩
使用 HPACK 算法来压缩首部内容
由于1.X中header带有大量的信息,并且得重复传输,2.0使用encoder来减少需要传输的hearder大小
注: Http2.0规范要求建立在TLS的基础上,也就是Https的请求。
http3.0
HTTP2.0 多请求复用一个TCP连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。 可以看出,这其实不是Http协议的问题,而是传输层协议的问题 所以 HTTP3.0 把 HTTP 下层的 TCP 协议改成了 UDP
Https和证书原理
SSL/TLS
SSL/TLS全称安全传输层协议(Transport Layer Security), 是介于TCP和HTTP之间的一层安全协议.
在没有经过任何加密手段的HTTP通信中,面临着三大危险:消息监听、消息篡改、冒充身份。
SSL/TLS协议就是为了解决这三大风险而设计的
SSL/TLS协议的基本思路是采用非对称加密,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
但涉及到两个问题
- 如何确保公钥未被篡改?
- 公钥加解密效率低(比对称加密算法慢100多倍)
解决办法:
- 将公钥放在数字证书中,只要证书是可信的,就认为公钥是可信的
- 每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。
因此,SSL/TLS协议基本过程为:
-
客户端向服务器端索要并验证公钥
-
双方协商生成"对话密钥"
-
双方采用"对话密钥"进行加密通信(对称加密)
其中1、2为握手阶段,非对称加密。
证书验证
-
服务器向证书机构(CA)申请证书,提供自己的域名、地址、公钥信息。
-
证书机构对服务器的信息使用hash算法得出一份128位的摘要,并对这份摘要使用证书机构的私钥进行非对称加密得到数字证书签名。
-
证书机构把服务器信息(明文)+数字签名+证书机构信息(包含证书机构公钥)发送给服务器。
-
客户端请求服务器时,服务器把证书返回给客户端。
客户端验证证书
-
客户端拿到证书,得到服务器信息(明文)、数字签名、证书机构信息。
-
客户端对服务器信息进行hash算法计算得到一份摘要S1。
-
客户端使用内置的证书机构提供的公钥对数字签名进行解密得到S2。
-
对比S1和S2可辨别证书是否来自服务器且没有经过篡改。
为什么对比S1/S2的一致性可以确认证书的可靠性
- 黑客是否可以使用自己的秘钥加密,并把证书机构的公钥修改成自己的公钥?
- 证书机构不多,系统会内置根证书机构的信息,包括的这些机构的公钥,这些公钥一定程度上是安全可信任的。客户端可以使用公钥对数字签名进行解密
- 系统预装证书机构是有限的,所以有二级证书机构,二级证书机构由根证书机构签发。二级证书再给服务器签发证书。
证书链
-
利用根证书机构给二级证书机构签发的时候同样是一份数字证书,其中包含了二级证书机构信息、数字签名、根证书机构信息。
-
服务器的数字证书中包含了二级证书机构的数字证书。
-
客户端使用根证书机构的公钥对二级证书机构的数字签名进行解密得到摘要再进行比对,得到二级证书机构的公钥。
-
使用二级证书机构的公钥对服务器证书进行验证。
-
同理,三级、四级证书机构验证都类同
注意事项
1.证书并不是直接对服务器信息进行加密,而是利用hash算法得到服务器摘要,再进行加密的。
Charles抓包原理
-> 客户端向服务器发起HTTPS请求
-> Charles拦截客户端的请求,伪装成客户端向服务器进行请求
-> 服务端返回CA证书给Charles
-> Charles拿到服务器CA证书,得到服务器公钥,然后将自己的证书返回给客户端
-> 客户端拿到Charles证书,得到Charles公钥,然后生成一个对称密钥,用Charles的公钥加密,发送给 Charles,这一步客户端能够得到Charles公钥的原因主要是因为将Charles的根证书安装到了手机
-> Charles收到客户端的对称密钥后,用自己的私钥解密对称密钥,然后用服务器公钥加密,发送给服务器
-> 服务器用自己的私钥解密对称密钥
-> 至此,连接建立,Charles拿到了 服务器公钥 和 客户端与服务器协商的对称密钥,之后就可以解密或修改加密的报文了。
主要原理就是:Charles作为中间人代理,拿到了 服务器证书公钥 和 HTTPS连接的对称密钥,前提是客户端选择信任并安装Charles的CA证书,否则客户端就会报警并中止连接。
安全模型
HTTPS并不是一个新的应用协议来取代HTTP,而是在HTTP的基础上,增加了网络安全的内容。
HTTPS的全称:Hyper Text Transfer Protocol over SecureSocket Layer,建立在安全socket层次上的超文本传输协议,可以认为HTTPS = HTTP+SSL。HTTPS与HTTP、TCP的关系如下:
imageHTTPS在HTTP和TCP之间建立了一个安全连接层 。SSL/TLS层次和TCP很类似,双方建立TCP连接之后,需要再建立安全连接。与TCP连接一样,SSL连接本质上,是对双方安全信息的记录,并不是一个真正意义上的连接。HTTP通过安全连接,即可与目标主机进行安全的通信,不怕被监听、篡改、冒充身份。
总结
http要解决的是网络安全问题
-
防止脚下监听:加密
-
防止消息篡改:hash算法
-
验证身份:数字证书
HTTPDNS
DNS
DNS( Domain Name System)是“域名系统”的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,它用于TCP/IP网络,它所提供的服务是用来将主机名和域名转换为IP地址的工作。
Http 请求的过程
- 发出请求
客户端发出一个请求,这个请求到达运营商的 DNS 服务器,然后被解析成对应的 IP 地址;
- 创建连接
第二步就是创建连接,会走 TCP 三次握手,然后根据 IP 地址找对对应的服务器,发送一个请求;
- 返回资源
服务器找到对应的资源,然后原路返回给客户端;
当我们发出请求解析 DNS 的时候,首先,会先连接到运营商本地的 DNS 服务器,由这个服务器帮我们去整棵 DNS 树上进行解析,然后将解析的结果返回给客户端。这其中,可能出现DNS被劫持
HTTPDNS
- HTTPNDS 不走传统的 DNS 协议,而是自己搭建基于 HTTP 协议的 DNS 服务器集群,分布在多个地点和多个运营商。
- 当客户端需要 DNS 解析的时候,直接通过 HTTP 协议进行请求这个服务器集群,得到就近的地址。
这就相当于基于 HTTP 协议,自己实现自己的域名解析。但是默认的域名解析都是走 DNS 的,因而使用 HTTPDNS 需要绕过默认的 DNS 路径,就不能使用默认的客户端。使用 HTTPDNS 的,往往是手机应用,需要在手机端嵌入支持 HTTPDNS 的客户端 SDK。
- 通过自己的 HTTPDNS 服务器和自己的 SDK,实现了域名解析。
使用 HTTPDNS 两个好处
- 防劫持
降低 Local DNS 劫持,绕过运营商域名解析过程;
- 提升速度
降低平均访问时长,因为节省了一次解析过程;
腾讯云和阿里云都提供了 HttpDNS 服务,具体的实现可能看他们的官方文档。
网友评论