目录:
1.TCP HTTP UDP三者的关系:
tcp
udp
http: http的结构,http1.0和2.0区别,HTTP3.0有什么改进? tcp协议, 状态码
2. 为什么要三次握手4次挥手?
3. Https和Http的区别
4. Https重要的3要素
5. 如何实现断点下载和断点上传?
6. 输入一串URL到浏览器都经历过什么?
7. 如何做网络优化
8. 多路复用 Okio
1.TCP HTTP UDP三者的关系:
1.1 三者的关系
网络模型:
TCP/IP是个协议组,可分为四个层次:网络接口层、网络层、传输层和应用层。
网络层:有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
传输层:中有TCP协议与UDP协议。
应用层:有HTTP,FTP、TELNET、SMTP、DNS等协议
3者的总结:
HTTP: 全称是HyperText Transfer Protocal,Http 协议是基于TCP 链接的。即:超文本传输协议,HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
TCP:传送控制协议(Transmission Control Protocol)
UDP:用户数据报协议 (UDP:User Datagram Protocol)
总结:tcp和udp是传输协议。http是应用层协议,IP是网络层
面试官: 请说出HTTP协议位于TCP/IP模型中的第几层?为什么说HTTP是可靠的数据传输协议?。
http位于TCP/IP中的应用层,因为http在传输层基于TCP协议而TCP协议是面向连接的可靠协议所以http可靠
tcp和udp的区别比较:
1).可靠和不可靠
2).TCP协议是面向连接;UDP协议采用无连接
Tcp实现socket和Udp实现socketet
TCP: ServerSocket ss = new ServerSocket(2000);
UDP: 创建DatagramSocket对象,DatagramSocket区别于Tcp方式下的socket对象。
3).报文协议区别
1.2 tcp TCP 流量控制与拥塞控制的理解
TCP 可靠传输原理实现(滑动窗口)。
确认和重传:接收方收到报文后就会进行确认,发送方一段时间没有收到确认就会重传。
数据校验。数据合理分片与排序, TCP 会对数据进行分片,接收方会缓存为按序到达的数据,重新排序后再提交给应用层。
流程控制:当接收方来不及接收发送的数据时,则会提示发送方降低发送的速度,防止包丢失。
拥塞控制: 当网络发生拥塞时,减少数据的发送
问题:TCP的拥堵机制和流量控制描述一下?tcp方面拥塞控制? (重点)
流量控制:是点对点通信量的控制,主要就是抑制发送端发送数据的速率,以便接收端来得及接收。
TCP使用折中的方式:滑动窗口协议,发送方和接收方都有滑动窗口。
窗口大小就是发送端在没有接收到确认应答时可以发送的数据大小。
利用滑动窗口机制,通过接收端返回的rwnd控制发送方的流量
发送方会根据接收方允许的窗口大小,调整自己发送的数据包大小,避免拥塞,这一步则是流量控制。
拥塞控制:
拥塞 当网络中存在过多的报文时,网络的性能就会相应下降,这种现象就被成为拥塞。即拥塞窗口小于数据数量,造成大量丢包,就会造成拥塞。
TCP拥塞控制的四个阶段
慢启动阶段
拥塞避免阶段
快速重传
快恢复阶段
这在接受数据方,这部分是因为在做面试准备的时候没有刻意看,导致面试的时候没有结构化的进行表述。整体可以总结为在做数据传输时,每一个tcp链接都有窗口大小平衡每个tcp的的传输速率(分配到的带宽窗口),窗口大小自然是动态的,通过控制窗口大小避免单个tcp占用过大带宽,导致传输拥塞
1.3 udp 如何优化
问题:UDP主要丢包原因及具体问题分析?
具体问题分析
1).发送频率过高导致丢包
很多人会不理解发送速度过快为什么会产生丢包,原因就是UDP的SendTo不会造成线程阻塞,也就是说,UDP的SentTo不会像TCP中的SendTo那样,直到数据完全发送才会return回调用函数,它不保证当执行下一条语句时数据是否被发送。(SendTo方法是异步的)这样,如果要发送的数据过多或者过大,那么在缓冲区满的那个瞬间要发送的报文就很有可能被丢失。至于对“过快”的解释,作者这样说:“A few packets a second are not an issue; hundreds or thousands may be an issue.”(一秒钟几个数据包不算什么,但是一秒钟成百上千的数据包就不好办了)。 要解决接收方丢包的问题很简单,首先要保证程序执行后马上开始监听(如果数据包不确定什么时候发过来的话),其次,要在收到一个数据包后最短的时间内重新回到监听状态,其间要尽量避免复杂的操作(比较好的解决办法是使用多线程回调机制)。
2).报文过大丢包
至于报文过大的问题,可以通过控制报文大小来解决,使得每个报文的长度小于MTU。以太网的MTU通常是1500 bytes,其他一些诸如拨号连接的网络MTU值为1280 bytes,如果使用speaking这样很难得到MTU的网络,那么最好将报文长度控制在1280 bytes以下。
3).发送方丢包
发送方丢包:内部缓冲区(internal buffers)已满,并且发送速度过快(即发送两个报文之间的间隔过短); 接收方丢包:Socket未开始监听; 虽然UDP的报文长度最大可以达到64 kb,但是当报文过大时,稳定性会大大减弱。这是因为当报文过大时会被分割,使得每个分割块(翻译可能有误差,原文是fragmentation)的长度小于MTU,然后分别发送,并在接收方重新组合(reassemble),但是如果其中一个报文丢失,那么其他已收到的报文都无法返回给程序,也就无法得到完整的数据了。
最大传输单元 MTU(Maximum Transmission Unit)
数据帧过大或过小都会影响传输的效率。例如会增加数据传输时的总时延。以太网 MTU 一般为 1500 字节。
面试官: 如何通过UDP来优化TCP的缺点?
UDP实现的可靠协议,基本都会对TCP的某一部分进行加强,另外一部分进行削弱。因为:
“实时性+可靠性+公平性” 三者不能同时保证,
如何设计在 UDP 上层保证 UDP 的可靠性传输?
udp如何实现可靠性传输?_3-Number-CSDN博客_udp如何实现可靠传输
传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照 tcp 可靠
1.简单来讲,要使用UDP来构建可靠的面向连接的数据传输,就要实现类似于TCP协议的超时重传,有序接受,应答确认,滑动窗口流量控制等机制,等于说要在传输层的上一层(或者直接在应用层)实现TCP协议的可靠数据传输机制。
简单来说:添加 seq/ack 机制,确保数据发送到对端
2.比如使用UDP数据包+序列号,UDP数据包+时间戳等方法,在服务器端进行应答确认机制,这样就会保证不可靠的UDP协议进行可靠的数据传输。
具体过程即是:送端发送数据时,生成一个随机 seq=x,然后每一片按照数据大小分配 seq。数据到达接收端后接收端放入缓存,并发送一个 ack=x 的包,表示对方已经收到了数据。发送端收到了 ack 包后,删除缓冲区对应的数据。时间到后,定时任务检查是否需要重传数据
参考现有的一些,基于udp的可靠传输协议有:RUDP、RTP、UDT
UDP本来存在丢包现象,现在的解决方案暂时考虑双方增加握手,这样做起来,就是UDP协议里面加上了TCP的实现方法.。程序中采用的是pthread处理,丢包率时大时小,不稳定可靠
1.4 http: http的结构,http1.0和2.0区别,HTTP3.0有什么改进? tcp协议, 状态码
1.4.1 http的结构,http1.0和2.0区别,HTTP3.0有什么改进? tcp协议
https://juejin.cn/post/6844904191123685389#heading-5
HTTP 1.0
短连接:每次发送请求都要重新建立tcp请求,即三次握手,非常浪费性能
HTTP 1.1
1). 长连接,HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。
-
多路复用(MultiPlexing),即连接共享, 支持方式是串行,Pipeling解决方式为,若干个请求排队串行化单线程处理,后面的请求等待前面请求的返回才能获得执行机会,一旦有某请求超时等,后续请求只能被阻塞,毫无办法,也就是人们常说的线头阻塞;
即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个 request, 每个连接的request可以随机的混杂在一 起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
HTTP 1.1 基于串行文件传输数据,因此这些请求必须是有序的,所以实际上我们只是节省了建立连接的时间,而获取数据的时间并没有减少
最大并发数问题,假设我们在 Apache 中设置了最大并发数 300,而因为浏览器本身的限制,最大请求数为 6,那么服务器能承载的最高并发数是 50
如上面所说,在HTTP1.1中是默认开启了Keep-Alive,他解决了多次连接的问题,但是依然有两个效率上的问题:
第一个:串行的文件传输。当请求a文件时,b文件只能等待,等待a连接到服务器、服务器处理文件、服务器返回文件,这三个步骤。我们假设这三步用时都是1秒,那么a文件用时为3秒,b文件传输完成用时为6秒,依此类推。(注:此项计算有一个前提条件,就是浏览器和服务器是单通道传输)
第二个:连接数过多。我们假设Apache设置了最大并发数为300,因为浏览器限制,浏览器发起的最大请求数为6,也就是服务器能承载的最高并发为50,当第51个人访问时,就需要等待前面某个请求处理完成。
.引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match
. HTTP1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206
HTTP2.0:
1).多路复用(链接共享):多个请求可同时在一个连接上并行执行。某个请求任务耗时严重,不会影响到其它连接的正常执行;
https://segmentfault.com/a/1190000011172823(类似于我做多线程分块下载)
2).二进制数据帧和流的概念,其中帧对数据进行顺序标识,这样浏览器收到数据之后,就可以按照序列对数据进行合并,而不会出现合并后数据错乱的情况。同样是因为有了序列,服务器就可以并行的传输数据。
HTTP/2 对同一域名下所有请求都是基于流,也就是说同一域名不管访问多少文件,也只建立一路连接。同样Apache的最大连接数为300,因为有了这个新特性,最大的并发就可以提升到300,比原来提升了6倍。
HTTP 3.0
基于google的QUIC协议,而quic协议是使用udp实现的
减少了tcp三次握手时间,以及tls握手时间
下载的时候速度越来越快?
浏览器请求//static.mtime.cn/a.js-->解析域名-->HTTP连接-->服务器处理文件-->返回数据-->浏览器解析、渲染文件
...
这样循环下去,直至全部文件下载完成。
这个流程最大的问题就是:每次请求都会建立一次HTTP连接,也就是我们常说的3次握手4次挥手,这个过程在一次请求过程中占用了相当长的时间,而且逻辑上是非必需的,因为不间断的请求数据,第一次建立连接是正常的,以后就占用这个通道,下载其他文件,这样效率多高啊!你猜对了,这就是Keep-Alive。
多域名提高浏览器的下载速度。之前我们有一个优化就是把css文件和js文件放到2个域名下面,这样浏览器就可以对这两个类型的文件进行同时下载,避免了浏览器6个通道的限制,这样做的缺点也是明显的,1.DNS的解析时间会变长。2.增加了服务器的压力。有了HTTP/2之后,根据上面讲的原理,我们就不用这么搞了,成本会更低
1.4.2 常用的状态码,401是什么意思?405?301?302?
301 redirect-----永久性转移
302 redirect-----暂时性转移
304 Not Modified
告诉客户端,你请求的这个资源至你上次取得后,并没有更改,你直接用你本地的缓存吧,我很忙哦,你能不能少来烦我啊!
401: 校验安全有问题,比如用户名密码或者系统安全
404 Not Found
你最不希望看到的,即找不到页面。如你在google上找到一个页面,点击这个链接返回404,表示这个页面已经被网站删除了,google那边的记录只是美好的回忆。
500 Internal Server Error
看到这个错误,你就应该查查服务端的日志了,肯定抛出了一堆异常,别睡了,起来改BUG去吧!
2. 为什么要三次握手4次挥手?
HTTP(HyperText Transfer Protocol)超文本传输协议是互联网上应用最为广泛的一种网络协议。由于信息是明文传输,所以被认为是不安全的。而关于HTTP的三次握手确认建立一个HTTP连接。TCP建立连接
2.1 具体的过程:
TCP三次握手(序列号变化,握手信号)
第一次握手(server确认状态),建立连接时使用的握手信号
建立连接。客户端发送连接请求报文段,将SYN位置为1,Sequence Number为x;然后,【客户端进入SYN_SEND状态,等待服务器的确认】;
SYN=1,Seq=x :第一次序列号 seq=x
第二次握手(server接受状态)Sequence number(序列号)
服务器收到SYN报文段。需要对这个SYN报文段进行确认,设置Acknowledgment Number为x+1(Sequence Number+1);同时,自己还要发送SYN请求信息,将SYN位置为1,Sequence Number为y;服务器端将上述所有信息放到一个报文段(即SYN+ACK报文段)中,一并发送给客户端,
【此时服务器进入同步收到状态;】
ACK报文=客户端SYN+1,同时发送SYN : 序列号 seq 变成y 。同时确认号ack=syn+1。syn往后移一位
第三次握手 Acknowledge number(确认号码)
客户端收到服务器的SYN+ACK报文段。然后将Acknowledgment Number设置为y+1,向服务器发送ACK报文段,这个报文段发送完毕以后,客户端和服务器端都进入ESTABLISHED状态,完成TCP三次握手。
ACK=1 ,确认有效 seq=x+1 。和第一次比进行了+1
名词解释
TCP的报文结构:ACK,SYN代表的意思,他们都是报文的结构,Seq:序列号
1、ACK 是TCP报头的控制位之一,对数据进行确认。确认由目的端发出, 用它来告诉发送端这个序列号之前的数据段都收到了。 比如确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性。
小的ack是干嘛用的?
和seq一样,也是确认号。
2、SYN 同步序列号,TCP建立连接时将这个位置1。
==============================
3个报文
1.seq:序号
2.syn:报文
3.ACK: 确认信号
2.2 问题: 为什么不可以是两次握手?
当客户端向服务器端发送一个连接请求时,由于某种原因长时间驻留在网络节点中,无法到达服务器端,
【由于TCP的超时重传机制】,当客户端在特定的时间内没有收到服务器端的的确认应答时,就会重新向服务器端发送连接请求,
该请求到达服务器端并建立连接,进行数据传输,当数据传输完成时,释放了TCP连接。
详细介绍:
若此时第一次的连接请求报文段延迟了一段时间后到达了服务器端,本来这是一个很早到达的失效的报文段,但是服务器端收到了该链接请求后误以为是客户端重新又发起了一次连接请求,于是服务器端发出确认应答报文段,并表示同意建立连接。
如果没有第三次握手,由于服务器端发送了确认应答信息,则表示新的连接建立成功,但是客户端并没有向服务器端发送任何建立请求,客户端将忽略服务器端的确认报文,更不会发送任何请求或数据。而服务器端认为建立成功了,并一直在等待建立连接,直到超出计数器的设定值,则认为服务器端出现了异常,并关闭此链接。这个等待的过程中,浪费了服务器端的资源。
一句话:超时,如果是三次握手将不会出现不该建立的连接。
2.3 :为什么要三次握手?
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
(比如:开始没有连上,然后后面第二个链路连上了。导致开始第一个链路失效的又传到服务器)
TCP 为什么三次握手不是两次握手,为什么两次握手不安全?
为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。
三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
保证:客户端和服务端收发正常。他们通过发送序号。0,1这种
面试官: 怎么看3次握手的过程?
通过FIddler抓包可以看到完整的流程
2.4 TCP四次分手
四次挥手
第一次分手:客户端发送报文告诉服务器没有数据要发送了(c----->s)
主机1(可以使客户端,也可以是服务器端),设置Sequence Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;
第二次分手:服务端收到,再发送给客户端告诉它我收到了(s------>c)
主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;
第三次分手:服务端向客户端发送报文,请求关闭连接 (s------>c)
主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;
第四次分手:客户端收到关闭连接的请求,向服务端发送报文,服务端关闭连接(c------>s)
主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。
2.4.2 为什么要四次分手
TCP协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP是全双工模式,
这就意味着,当主机1发出FIN报文段时,只是表示主机1已经没有数据要发送了,主机1告诉主机2,它的数据已经全部发送完毕了;
但是,这个时候主机1还是可以接受来自主机2的数据;当主机2返回ACK报文段时,表示它已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的;
当主机2也发送了FIN报文段时,这个时候就表示主机2也没有数据要发送了,就会告诉主机1,我也没有数据要发送了,之后彼此就会愉快的中断这次TCP连接。
四次的目的:防止数据未加载完就断开的情况
链接是3次握手,断开是4次。
多了一次,是服务器网客户端发送都时候,分2次发送。一次是确认,另外一次是发送未完的消息
3. Https和Http的区别
表格:
Http:采用 请求—响应 方式。即建立网络连接后,当 客户端 向 服务器 发送请求后,服务器端才能向客户端返回数据。可理解为:是客户端有需要才进行通信HTTPS通信原理
HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议 它是一个安全通信通道, 应用层协议,TCP是传输层协议,在应用层和传输层之间,增加了一个安全套接层SSL/TLS:
https协议需要到CA申请证书。
http是超文本传输协议,信息是明文传输;https 则是具有安全性的ssl加密传输协议。
也就是通过第三方工具可以截取篡改http传输的数据,而https即使截获了没有密钥也白搭。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
http默认使用80端口,https默认使用443端口
4. Https重要的3要素
4.0 整体的一个流程
1). 客户端发起HTTPS请求
客户端向服务器发起HTTPS请求,连接到服务器的443端口:这个没什么好说的,就是用户在浏览器里输入一个https网址,然后连接到server的443端口。
2). 服务端的配置
服务器端有一个密钥对,即公钥和私钥,是用来进行非对称加密使用的,服务器端保存着私钥,不能将其泄露,公钥可以发送给任何人。(可以想象成一把钥匙和一个锁头)
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。这套证书其实就是一对公钥和私钥。
3). 传送证书
服务器将自己的公钥发送给客户端。这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间,颁发者的签名等等。
4). 客户端解析证书
这部分工作是有客户端的TLS来完成的,验证其合法性,如果发现发现证书有问题,那么HTTPS传输就无法继续。严格的说,这里应该是验证服务器发送的数字证书的合法性,关于客户端如何验证数字证书的合法性,下文会进行说明。如果公钥合格,那么客户端会生成一个随机值,这个随机值就是用于进行对称加密的密钥,我们将该密钥称之为client key,即客户端密钥,这样在概念上和服务器端的密钥容易进行区分。然后用服务器的公钥对客户端密钥进行非对称加密,这样客户端密钥就变成密文了,至此,HTTPS中的第一次HTTP请求结束。(这里非对称加密????)
5). 传送加密信息
客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
这个随机值的重要性!
6). 服务段解密信息
服务器用私钥解密,得到客户端的随机值是非对称加密,解密之后的明文就是客户端密钥,然后用客户端密钥对数据进行对称加密,这样数据就变成了密文。
对称加密:内容传输的时候
7). 传输加密后的信息
然后服务器将加密后的密文发送给客户端。
8). 客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策
客户端收到服务器发送来的密文,用客户端密钥对其进行对称解密,得到服务器发送的数据。这样HTTPS中的第二个HTTP请求结束,整个HTTPS传输完成。
HTTPS在传输的过程中会涉及到三个密钥:
服务器端的公钥和私钥,用来进行非对称加密, 解密客户端随机密钥
客户端生成的随机密钥,用来进行对称加密, 加密信息
4.1 TLS和SSL
SSL (Secure Socket Layer,安全套接字层),SSL使用40 位关键字作为RC4流加密算法
TLS (Transport Layer Security,传输层安全协议) 更高级, ssl升级版
TLS它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,主要是它们所支持的加密算法不同,TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:
为什么用https的原因?
4.1.2) TLS 1.3 VS TLS 1.2的区别:
https://www.jianshu.com/p/efe44d4a7501
总结一下,TLS 1.3 与以前的版本相比具有如下两个大的优势,分别是:
1).更快的访问速度
- . 更强的安全性
4.1.3 不使用SSL/TLS的HTTP通信,就是不加密的通信,所有的信息明文传播,带来了三大风险:
窃听风险:第三方可以获知通信内容。
篡改风险:第三方可以修改通知内容。
冒充风险:第三方可以冒充他人身份参与通信。
SSL/TLS协议是为了解决这三大风险而设计的,希望达到:
所有信息都是加密传输,第三方无法窃听。
具有校验机制,一旦被篡改,通信双方都会立刻发现。
配备身份证书,防止身份被冒充。
Https的作用,就是弥补Http的不足
内容加密 建立一个信息安全通道,来保证数据传输的安全;
身份认证 确认网站的真实性
数据完整性 防止内容被第三方冒充或者篡改
4.2 CA证书
CA(Certificate Authority)是负责管理和签发证书的第三方权威机构,是所有行业和公众都信任的、认可的。
CA证书,就是CA颁发的证书,可用于验证网站是否可信(针对HTTPS)、验证某文件是否可信(是否被篡改)等,也可以用一个证书来证明另一个证书是真实可信,最顶级的证书称为根证书。除了根证书(自己证明自己是可靠),其它证书都要依靠上一级的证书,来证明自己。
证书的作用:所以通过发送 SSL 证书的形式,既解决了公钥获取问题,又解决了黑客冒充 问题,一箭双雕,HTTPS 加密过程也就此形成
问题的难点是如果我们选择直接将公钥传递给客户端的方案,我们始终无法解决公钥传递被中间人调包的问题。
所以,我们不能直接将服务器的公钥传递给客户端,而是第三方机构使用它的私钥对我们的公钥进行加密后,再传给客户端。客户端再使用第三方机构的公钥进行解密。
下图就是我们设计的第一版“数字证书”,证书中只有服务器交给第三方机构的公钥,而且这个公钥被第三方机构的私钥加密了:
只有认证机构可以生成证书吗?
如果需要浏览器不提示安全风险,那只能使用认证机构签发的证书。
但浏览器通常只是提示安全风险,并不限制网站不能访问,所以从技术上谁都可以生成证书,只要有证书就可以完成网站的 HTTPS 传输。
为什么需要 CA 认证机构颁发证书?
HTTP 协议被认为不安全是因为传输过程容易被监听者勾线监听、伪造服务器,而 HTTPS 协议主要解决的便是网络传输的安全性问题。
首先我们假设不存在认证机构,任何人都可以制作证书,这带来的安全风险便是经典的“中间人攻击”问题。
浏览器如何验证证书的合法性?如何鉴别证书是不是伪造的?
判断证书是否被篡改。需要与 CA 服务器进行校验。
判断证书是否已吊销。通过 CRL(Certificate Revocation List 证书注销列表)和 OCSP(Online Certificate Status Protocol 在线证书状态协议)实现。
其中 OCSP 可用于第 3 步中以减少与 CA 服务器的交互,提高验证效率。
客户端校验服务端的数字证书的过程,
1).客户端得到证书后,利用证书中的公钥去解密该 Hash 值,得到 Hash-a ;
2). 然后再利用证书内的签名 Hash 算法去生成一个 Hash-b 。
- 最后比较 Hash-a 和 Hash-b 这两个的值。如果相等,那么证明了该证书是对的,服务端是可以被信任的;如果不相等,那么就说明该证书是错误的,
4.3 中间人攻击
中间人攻击的情况,比如:伪造证书
中间人攻击的过程
服务器向客户端发送公钥。
攻击者截获公钥,保留在自己手上。
然后攻击者自己生成一个【伪造的】公钥,发给客户端。
客户端收到伪造的公钥后,生成加密hash值发给服务器。
攻击者获得加密hash值,用自己的私钥解密获得真秘钥。
同时生成假的加密hash值,发给服务器。
服务器用私钥解密获得假秘钥。
这里就需要一个强大的公证人,就是CA,操作系统会做CA证书的判断。
分析:
证书是公开的,如果要发起中间人攻击,我在官网上下载一份证书作为我的服务器证书,那客户端肯定会认同这个证书是合法的,如何避免这种证书冒用的情况?
其实这就是非加密对称中公私钥的用处,虽然中间人可以得到证书,但私钥是无法获取的。
一份公钥是不可能推算出其对应的私钥,中间人即使拿到证书也无法伪装成合法服务端,因为无法对客户端传入的加密数据进行解密。
如何方式中间人攻击?
1).尽可能保证证书不要被伪造。保证证书是ca证书,由权威机构颁发
2).服务器的私钥不要被获取到
3). 先预先生成需要的正式放在本地,然后https请求过程中得到的证书与本地进行比较
如何保证公钥不被篡改?如何保证公钥是服务器下发的 ?(平安)
解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
总结:防止证书伪造,防止公钥掉包,防止中间人冒充服务器 。所以https通信关键点:证书和私钥
问题:Https安全的原因?
1).每次都是用的随机密钥,之前是固定的公钥
2).证书
问题: 怎么知道证书是不是正确的?
问题:解决2个重要问题
1.如何确保自己的服务器是正确的?如何确认服务器是真实的而不是黑客?
首先:SSL 证书
其次: 客户端校验证书是否正常。
为什么用了 HTTPS 就是安全的?HTTPS 的底层原理如何实现?用了 HTTPS 就一定安全吗?
因为 HTTPS 保证了传输安全,防止传输过程被监听、防止数据被窃取,可以确认网站的真实性。
客户端发起 HTTPS请求,服务端返回证书,客户端对证书进行验证,验证通过后本地生成用于改造对称加密算法的随机数,通过证书中的公钥对随机数进行加密传输到服务端,服务端接收后通过私钥解密得到随机数,之后的数据交互通过对称加密算法进行加解密。
4.4 双向验证
要说明什么是双向认证,就先说明什么是单向认证。
1:在普通的场景中,例如我们访问https://www.baidu.com,客户端会和服务器会进行SSL握手,进行密钥协商与身份认证,这个身份认证就是单向认证,又叫服务器认证,即 客户端需要认证服务器身份,客户端如何认证服务器身份呢?
单向验证过程中,客户端会验证自己访问的服务器,服务器对来访的客户端身份不做任何限制。如果服务器需要限制客户端的身份,则可以选择开启服务端验证,这就是双向验证。从这个过程中我们不难发现,使用单向验证还是双向验证,是服务器决定的。
近期在做IP切换的HTTPS访问时,遇到了一些问题:客户端如何进行HTTPS的证书验证。
其实对于一般的项目基本都是做的单向验证,即在客户端证书或者HOST的验证;对于金融、银行相关的项目才会使用的双向验证,客户端与服务端之间都要对彼此进行验证,以防止中间人进行攻击。
总结一下:
1、单向验证中,如果是你客户端,你需要拿到服务器的证书,并放到你的信任库中;如果是服务端,你要生成私钥和证书,并将这两个放到你的密钥库中,并且将证书发给所有客户端。
2、双向验证中,如果你是客户端,你要生成客户端的私钥和证书,将它们放到密钥库中,并将证书发给服务端,同时,在信任库中导入服务端的证书。如果你是服务端,除了在密钥库中保存服务器的私钥和证书,还要在信任库中导入客户端的证书。
3、再次强调,使用单向验证还是双向验证,是服务器决定的。
https
https://blog.csdn.net/m0_56217379/article/details/115463482
5. 如何实现断点下载和断点上传?
6. 输入一串URL到浏览器都经历过什么?
7. 如何做网络优化
8. 多路复用 Okio
okhttp用了自己的okio
implementation 'com.squareup.okhttp3:okhttp:3.3.0'
implementation 'com.squareup.okio:okio:1.5.0'