计算机网络面试篇
HTTP
常见字段
- Host 字段
客户端发送请求时,用来指定服务器的域名。
- Content-Length 字段
服务器在返回数据时,会有Content-Length 字段,表明本次回应的数据长度。
- Connection 字段
最常用于客户端要求服务器使用「HTTP 长连接」机制,以便其他请求复用。
- Content-Type 字段
用于服务器回应时,告诉客户端,本次数据是什么格式。
- Content-Encoding 字段
说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式
缓存技术
强制缓存
指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动性在于浏览器这边。
强缓存是利用下面这两个 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。
协商缓存
协商缓存为服务器告知客户端此处可以使用本地缓存,让两者共同协商是否使用缓存。
两种实现方式:
- 基于时间实现
根据请求头的Last-Modified
和响应头的If-Modified-Since
判断,前者是响应资源的最后一次修改时间,进行时间对比后判断是否过期。
- 基于唯一标识实现
请求头部中的 If-None-Match
字段与响应头部中的 ETag
字段
后者是资源的唯一标识,进行比较后判断返回200或者304状态码
注意协商缓存必须和强制缓存共同使用,即一定会先判断是否有强制缓存
⭐⭐⭐HTTP演变
HTTP/1.1 和 HTTP/2.0 传输协议使用的是 TCP 协议,而到了 HTTP/3.0 传输协议改用了 UDP 协议。
HTTP1.1做了什么
- 长连接
减少了不必要的tcp的建立连接和断开连接
- 管道运输通信
因为有了长连接,请求可以不必等响应回来就能继续发送请求
- 队头阻塞
上面说的因管道解决的是请求的队头阻塞,但是没有解决响应的队头阻塞,因为服务器需要按顺序执行请求
补充:http1.1默认是不开启管道通信的,故http1.1其实还是基于请求-响应模型,还是会等待响应而无法做其他的事
HTTP1.1应该如何优化
通过缓存技术来避免发送 HTTP 请求。客户端收到第一个请求的响应后,可以将其缓存在本地磁盘,下次请求的时候,如果缓存没过期,就直接读取本地缓存的响应数据。如果缓存过期,客户端发送请求的时候带上响应数据的摘要,服务器比对后发现资源没有变化,就发出不带包体的 304 响应,告诉客户端缓存的响应仍然有效。
减少 HTTP 请求的次数,有以下的方法:
- 将原本由客户端处理的重定向请求,交给代理服务器处理,这样可以减少重定向请求的次数
- 合并资源:将多个小资源合并成一个大资源再传输,能够减少 HTTP 请求次数以及 头部的重复传输,再来减少TCP 连接数量,进而省去 TCP 握手和慢启动的网络消耗,
- 按需访问资源,只访问当前用户看得到/用得到的资源,当客户往下滑动,再访问接下来的资源,以此达到延迟请求,也就减少了同一时间的 HTTP 请求次数
通过压缩响应资源,降低传输资源的大小,从而提高传输效率,比如有无损压缩和有损压缩
HTTP1.1的缺点
请求/响应头部(Header)未经压缩就发送,首部信息越多延迟越大。只能压缩 Body 的部分
发送冗长的首部。每次互相发送相同的首部造成的浪费较多;
服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是队头阻塞
没有请求优先级控制
请求只能从客户端开始,服务器只能被动响应
HTTP2.0做了什么
HTTP/2 协议是基于 HTTPS 的,所以 HTTP/2 的安全性也是有保障的
- 头部压缩
客户端和服务器共同维护一张头信息表,,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度了。
- 数据压缩
采用二进制压缩为头信息帧和数据帧,增加了数据传输的效率
- 并发传输
基于Stream流,多个 Stream 复用在一条 TCP 连接,可以同时推送多个message,一个message是http2.0的一个基本单位,一个message里可以包含多个原有的http1.1里的请求,故达到了多个请求同时传输发送的效果。
同时还能根据streamid来有序拼接message里的信息
- 服务器推送
这个stream流可以是双方的,两边发送的streamid用奇偶数划分哪个是客户端发的哪个是服务器发的,一般是客户端发的是奇,服务器发的是偶。
HTTP2.0的缺点
因为基于TCP实现,多个stream都是复用一个tcp连接,那么如果一个tcp包在传输过程中丢失了就会触发tcp重传,那么所有的http的请求就都要等待这个tcp包的重传,这就是http2.0的队头阻塞。
待补充。。。
HTTP3做了什么
HTTPS
概述
本质上就是在TCP到HTTP中加了一层安全层 (SSL/TLS)
做了三件事:
- 信息加密:保证信息被加密后无法被窃取
- 校验机制:不让信息被篡改
- 身份证书:证明身份
信息加密
使用的是混合加密的方式解决,即对称加密+非对称加密
在通信建立前采用非对称加密的方式交换「会话秘钥」,后续就不再使用非对称加密
在通信过程中全部使用对称加密的「会话秘钥」的方式加密明文数据。
校验机制
摘要算法
为了保证内容不被篡改,先对内容进行一次哈希运算得到基于内容的哈希值,然后将内容和哈希值一起发送过去,对方拿到内容后也进行哈希运算,如果哈希运算得到的结果和传递过来的哈希的结果相同,那么就是没有被篡改,反之就是被修改了
数字签名
光靠摘要算法并不能完全解决问题,如果传输过程中内容+哈希值
一起被替换了,那么到了对方手里,对方还是拿内容进行哈希运算,得到的哈希结果和传递过来的哈希值也是一样的;
所以还要先对哈希值进行私钥加密,得到一个数字签名,然后将内容+数字签名一起发送出去,这样对方拿到这个数字签名后,可以用公钥解密,这样就不会被冒充了
私钥加密,公钥解密:可以保证消息的传递者是可靠的,不被冒充
公钥加密,私钥解密:可以保证内容传输的安全
所以校验机制是靠摘要算法+数字签名两个一起解决的
身份证书
从上述的流程中,如果公私钥这一对被替换了,那么也会有被冒充的风险,所以要保证这个公钥是真的,得让客户端去CA里验证这个公钥是不是真的,由于服务端已经将公钥在CA里注册了,所以CA里有服务器的公钥信息,所以客户端对这个数字证书是可信的。
建立连接过程
TLS总共四次握手过程:
第一次:
客户端发起client hello请求,发送内容有:
- 客户端自己所能接受的TLS版本
- 客户端自己生成的一个随机数,客户端自己也会保存一份在自己这里
- 客户端支持的加密算法
第二次:
服务端收到来自客户端的请求之后,对其发送的内容有:
- 如果对于客户端发送过来的TLS版本不合适,就终止连接
- 服务端自己也生成一个随机数发给客户端,自己也在服务端保存一份
- 发送加密算法
- 发送从CA注册好的数字证书
第三次:
客户端收到服务端发来的消息后,做下面这些事:
拿着服务端发送过来的数字证书和保存在操作系统或浏览器的公钥去对该数字证书进行认证,如果认证失败证明证书不可信,可以选择不继续后续的操作
如果证书可信,那么客户端再生成一个随机数,并将该随机数用服务端的公钥进行加密发送过去
发送一个加密算法改变的通知给服务端,告诉服务端下次开始使用加密通信
发送一个握手结束的通知,把上述的信息内容摘要也发送给服务端,供服务端校验
第四次:
服务端收到消息之后,做下面这些事:
- 拿自己的私钥对该随机数进行解密,同时用三个随机数来生成加密的密钥,后续都是通过这个密钥来进行对称加密
- 发送加密算法改变的通知给客户端,告诉其下次开始用加密通信
- 发送一个握手结束的通知,同样把上述信息摘要给客户端,供其校验
CA验证过程
服务端生成数字证书的过程:
- 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash.计算,得到一个 Hash 值;
- 然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate signature,也就是 CA 对证书做了签.名;
- 最后将 Certificate signature 添加在文件证书上,形成数字证书;
客户端校验服务端的数字证书的过程:
- 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
- 通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密Certificate Siqnature 内容,得到一个 Hash 值 H2:
- 最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
证书信任链问题
操作系统或浏览器一般只会信任根证书,再由根证书下来的一层一层的中间证书,依次进行对下级证书进行保证,形成一个证书信任链。
拿根证书的公钥去验证下一级证书是否可信,一路验证下来到最终我们要建立连接的服务端的证书。
RSA和ECDHE
在HTTPS协议中,RSA算法作为一种非对称加密算法,被用来在客户端和服务端之间安全地交换对称密钥。尽管RSA算法在早期的HTTPS握手过程中扮演了重要角色,但它存在一些固有的缺陷。下面详细探讨这些缺陷以及ECDHE算法是如何解决这些问题的。
RSA算法的缺陷
- 不支持前向保密:使用RSA密钥协商算法时,客户端会生成一个随机数(用于生成对称加密密钥),并通过服务端的公钥加密后发送给服务端。服务端使用私钥解密得到这个随机数。这种方式的主要问题是不支持前向保密。这意味着一旦服务端的私钥泄露,所有过去被第三方截获的TLS通信密文都可能被破解。
- 性能效率:RSA算法在加密和解密过程中需要进行大量的数学运算,尤其是大数的乘法和模幂运算,这导致加密和解密的速度较慢。在处理大量数据时,这种性能瓶颈尤为明显。
- 密钥长度:为了保持足够的安全性,RSA密钥的长度需要相对较长,例如2048位或更长。这增加了计算资源的需求,尤其是在加密和解密过程中。
- 安全性依赖:RSA算法的安全性依赖于大数分解的难度,而随着计算能力的进步,特别是未来量子计算的发展,这种难度可能会降低。
ECDHE算法如何解决这些问题
ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)算法是一种基于椭圆曲线密码学(ECC)的密钥交换协议,它解决了RSA算法存在的许多问题:
- 支持前向保密:ECDHE每次握手都会生成一个新的临时密钥对,即使服务器的长期密钥被泄露,过去会话的安全性也不会受到影响。这是因为每个会话使用独立的一次性密钥,而不是长期密钥。
- 更高的安全性与更小的密钥长度:ECC算法使用较小的密钥长度就能达到与RSA相同甚至更高的安全性水平。例如,一个256位的ECC密钥提供的安全性大致相当于3072位的RSA密钥。这意味着ECC在抵御密码攻击方面更为高效。
- 性能提升:ECC所需的密钥长度更短,有效降低了计算资源消耗和存储需求,提高了加密与解密的速度。
- 兼容性和普遍适用性:尽管RSA在兼容性和普遍适用性上仍占有一定优势,但ECC因其高效特性而逐渐受到更多关注并得到广泛应用。
总结
RSA算法在HTTPS中的主要缺陷在于不支持前向保密、性能效率低下以及密钥长度较长等问题。ECDHE算法通过支持前向保密、使用更小的密钥长度以及提供更高的安全性来解决这些问题。因此,在现代HTTPS协议中,ECDHE成为了更优选的密钥交换算法。
通过采用ECDHE算法,不仅可以提高HTTPS的安全性,还能显著改善性能表现,这对于现代Web应用而言是非常重要的。
HTTPS如何保证消息可靠性
上面的握手协议是获取加密算法的,保证可靠性是由记录协议来实现的
- 首先,消息被分割成多个较短的片段,然后分别对每个片段进行压缩。
- 接下来,经过压缩的片段会被加上消息认证码(MAC值,这个是通过哈希算法生成的),这是为了保证完整性,并进行数据的认证。通过附加消息认证码的 MAC值,可以识别出篡改。与此同时,为了防止重放攻击,在计算消息认证码时,还加上了片段的编码。
- 再接下来,经过压缩的片段再加上消息认证码会一起通过对称密码进行加密
- 最后,上述经过加密的数据再加上由数据类型、版本号、压缩后的长度组成的报头就是最终的报文数
据。
HTTPS一定可靠吗
基本上是可靠的,但是对于伪造证书,浏览器或者操作系统其实也可以识别出来伪造的证书是假的,但是在浏览器上你依然可以选择信任该证书,继续访问,这样就不可靠了。
HTTPS如何优化
TCP
三次握手
TCP 使用三次握手建立连接的最主要原因是防止「历史连接」初始化了连接。
同步双方初始序列号
避免资源浪费
四次挥手
可以变成三次挥手吗
在一些情况下是可以的
超时重传
滑动窗口
流量控制
拥塞控制
⭐⭐⭐TCP 序列号和确认号是如何变化的?
三次握手中
数据传输中
四次挥手中
UDP
DNS
WebSocket
概念介绍
socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。
WebSocket协议是基于TCP的一种新的网络协议,和http协议一样属于应用层协议,是一种让客户端和服务器之间能进行双向实时通信的技术。
具体见本站连接