计算机网络
OSI七层模型
协议,作用
物理层:建立、维护、断开物理连接
提供物理连接;实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。使其上面的数据链路层不必考虑网络的具体传输介质是什么
链路层:建立逻辑连接、进行硬件地址寻址、差错校验等功能
建立管理节点间的链路;接受来自物理层的比特流形式的数据并封装成帧传送到上一层,将来自上层的数据帧拆装为比特流形式的数据发送给物理层;通过mac地址在网络内部找到host
网络层:进行逻辑地址寻址,实现不同网络之间的路径选择
通过路由选择算法为报文或分组通过通信子网选择最适当的路径;链路层数据帧在网络层被转换为数据包,在不同网络中进行传输;在不同网络间通信时通过唯一的ip地址(逻辑地址)识别设备,通过路由器连接不同的网络并计算出传送路径
传输层:建立,管理和维护端到端的连接
定义了传输数据的协议及端口号(TCP传输效率低可靠性高,发消息等允许延迟不允许丢包,UDP效率高可靠性低,视频聊天等允许丢包不允许延迟),将从下层接受到的数据进行分段和传输,到达目的地址之后再重组,同时进行流量控制,根据接收方接收数据的快慢程度,规定适当的发送速率,解决传输效率及能力的问题
会话层,表示层不提了
应用层:网络服务与最终用户的一个接口,规定应用程序如何进行通信
直接向用户的应用程序提供网络服务,进行文件传输,文件管理,电子邮件的信息处理
IP
IP Packet
Version:版本号
Header length:头长度
Type of service:服务类型
Datagram length:数据报长度
Identifier, flags, fragmentation offset:用来分片(IP fragmentation),链路层有最大传输限制(MTU),通过分片保证IP包可以分成符合MTU的小片从而在不同局域网之间传输
Time-to-live:确保ip packet不会在网络中一直被传下去
Protocol:传输层用的啥协议
Header checksum:校验用的
Source and destination IP addresses:两边的ip地址
Options:一般不用
ARP协议
ARP协议是用来在局域网内找IP对应的MAC的
源主机先在自己的ARP缓冲区中寻找映射,如果有(直接填充于以太网帧中),如果没有,通过路由广播向局域网内每一台主机进行请求,这时一些联网的主机就会收到这个请求,并将这个请求传回网络层,对比IP地址,检验是否可以接受,如果不行,则直接丢失这个信息,如果可以那么回复ARP请求,并且将源主机的MAC地址加入到目的ARP缓冲区中,形成映射,源主机接受到请求后,将目的的MAC地址加入到ARP缓冲区,也形成映射,并将mac地址传输至连接层。此时转化完成
TCP/UDP
TCP,UDP区别,应用场景
TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接(三次握手/四次挥手),丢包重发,分包顺序乱了会进行顺序控制;提供拥塞控制 UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务,传输数据之前源端和终端不建立连接。并且它是将应用程序发来的数据在收到的那一刻,立刻按照原样发送到网络上的一种机制。没有拥塞控制,(网络出现拥塞不会使源主机的发送速率降低),丢包不重发。包的到达顺序乱掉也不纠正。
1、TCP面向连接,需要先建立连接;UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,当应用程序传送的数据块太长会把它划分短一些再传送,如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去;UDP是面向报文的,应用层交给UDP多长的报文,UDP就照样发送
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小只有8个字节
TCP用于在传输层有必要实现可靠传输的情况:SMTP,SSH,HTTP,FTP,
UDP用于那些对高速传输和实时性有较高要求的通信或广播通信:DNS,TFTP
TCP segment
Sequence & Acknowledgment:确保可靠传输
Receive window:流量控制
Header length:TCP头部长度(options一般为空,所以长度一般为20bytes)
Option field:用于协商MSS
ACK:Acknowledgment是否有效
RST & SYN & FIN:三次握手四次挥手
PSH & URG:一般不用
Urgent data pointer:提示紧急信息位置
Internet checksum:校验和
UDP segment
三次握手/四次挥手
第一次握手:主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B,向主机B 请求建立连接,通过这个数据段, 主机A告诉主机B 两件事:我想要和你通信,你可以用哪个序列号作为起始数据段来回应我
第二次握手:主机B 收到主机A的请求后,用一个带有确认应答和同步序列号标志位的数据段响应主机A,也告诉主机A两件事:我已经收到你的请求了,你可以传输数据了;你要用那个序列号作为起始数据段来回应我
第三次握手:主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B 的数据段:我已收到回复,我现在要开始传输实际数据了,这样3次握手就完成了,主机A和主机B 就可以传输数据了
TCP建立连接要进行3次握手,而断开连接要进行4次
第一次: 当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求 ;
第二次: 主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1;
第三次: 由B 端再提出反方向的关闭请求,将FIN置1 ;
第四次: 主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.。
seq:序列号,传了多少数据
ACK:确认字段,仅当ACK=1时确认号字段有效,连接建立后所有传送报文段ACK=1
ack number:确认号码,为N表示N-1为止所有数据都正确收到
SYN:发起一个连接。在握手完成后SYN为1,表示TCP建立已连接。此后的所有报文段中,SYN都被置0。
FIN:释放一个连接。如果源主机数据发送完毕,将把该连接下要发送的最后一个报文段的报头中的FIN位置1,或将该报文段后面发送的报头中该位置1。
为啥要三次握手
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。”
为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,**它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,**所以你可能未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
RST是干啥的
三次握手中第三次的ACK丢失,导致Client认为连接已经建立但是实际上并没有建立连接时,Client向server发包,server会用RST回应,表示连接尚未建立
TCP协议如何确保可靠性传输
(校序重流拥)
确认应答+序列号:TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层。
超时重传:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
EstimatedRTT = (1 – a ) • EstimatedRTT + a • SampleRTT
DevRTT = (1 – b ) • DevRTT + b • | SampleRTT – EstimatedRTT |
TimeoutInterval = EstimatedRTT + 4 • DevRTT
校验和:在发送方将整个报文段分为多个16位的段,然后将所有段进行反码相加,将结果存放在检验和字段中,接收方用相同的方法进行计算,如最终结果为检验字段所有位是全1则正确
连接管理:三次握手四次挥手。
如上
流量控制: TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失
LastByteRcvd – LastByteRead <= RcvBuffer
rwnd = RcvBuffer – [LastByteRcvd – LastByteRead]
LastByteSent – LastByteAcked <= rwnd
拥塞控制:当网络拥塞时,减少数据的发送
TIME_WAIT的意义(为什么要等于2MSL)
- 可靠的终止TCP连接
若处于time_wait的client发送给server确认报文段丢失的话,server将在此又一次发送FIN报文段,那么client必须处于一个可接收的状态就是time_wait而不是close状态。
- 保证迟来的TCP报文段有足够的时间被识别并丢弃
linux 中一个TCPport不能打开两次或两次以上。当client处于time_wait状态时我们将无法使用此port建立新连接,假设不存在time_wait状态,新连接可能会收到旧连接的数据;2MSL可以保证所有旧连接的数据在这个过程中全部死亡
time_wait持续的时间是2MSL,保证旧的数据能够丢弃。由于网络中的数据最大存在MSL(maxinum segment lifetime)
为什么序列号要随机初始化
minimize the possibility that a segment that is still present in the network from an earlier, already-terminated connection between two hosts is mistaken for a valid segment in a later connection between these same two hosts (which also hap- pen to be using the same port numbers as the old connection)
UDP如何实现可靠传输
因为UDP是无连接的协议,所以在传输层上无法保证可靠传输,要想实现可靠传输,只能从应用层实现。需要实现seq/ack机制,重传机制和窗口确认机制。
就要接收方收到UDP之后回复个确认包,发送方有个机制,收不到确认包就要重新发送,每个包有递增的序号,接收方发现中间丢了包就要发重传请求,当网络太差时候频繁丢包,防止越丢包越重传的恶性循环,要有个发送窗口的限制,发送窗口的大小根据网络传输情况调整,调整算法要有一定自适应性
流量控制
所谓流量控制就是让发送方发送速率不要过快,让接收方来得及接收。利用TCP报文段中的窗口大小字段来控制发送方的发送窗口不大于接收方发回的窗口大小就可以实施流量控制。
问题:接收方若没有缓存足够使用,就会发送零窗口大小的报文,此时发送放将发送窗口设置为0,停止发送数据。之后接收方有足够的缓存,发送了非零窗口大小的报文,但是这个报文在中途丢失的,那么发送方的发送窗口就一直为零导致死锁。
解决这个问题:只要TCP的一方收到对方的零窗口通知,就周期性的发送一个1 byte的零窗口探测报文段。对方就在确认这个报文的时候给出现在的窗口大小(注意:TCP规定,即使设置为零窗口,也必须接收以下几种报文段:零窗口探测报文段、确认报文段和携带紧急数据的报文段)
拥塞控制
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
ssthresh:慢开始阈值
- 慢启动:慢启动算法的思路是当主机开始发送数据时,先以比较小的拥塞窗口进行发送,然后每次翻倍,也就是说,由小到大逐渐增加拥塞窗口的大小,而这个大小是指数增长的,即1、2、4、8、16 MSS 为了防止拥塞窗口cwnd增长过大引起网络拥塞,还要另外设置一个慢启动阈值ssthresh状态变量,当拥塞窗口的大小超过慢启动阈值的时候( cwnd > ssthresh 时),停止使用慢开始算法而改用拥塞避免算法
- 拥塞避免:拥塞避免算法的思路是让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1 MSS,而不是加倍。
- 快速重传:当发送端连续收到三个重复的ack时,表示该数据段已经丢失,需要重发。此时慢启动阈值ssth变为cwnd一半,拥塞窗口cwnd变为ssth+3 MSS,然后+1+1的发(每一轮rtt+1 MSS)
- 快速恢复:当超过设定的时间没有收到某个报文段的ack时,表示网络拥塞,慢启动阈值ssth变为cwnd一半,拥塞窗口cwnd=1 MSS,进入慢启动阶段
MSS: maximum segment size,等于MTU减去-TCP/IP头部的大小
粘包如何解决
- 添加报文长度
- 每个报文结尾加分隔符
- 报文设置固定长度
- 发送方关闭nagle算法
SOCKET是什么,经常使用吗?
socket是应用层与传输层的一个抽象,将复杂的TCP/IP协议隐藏在Socket接口之后,只对应用层暴露简单的接口
socket是一种特殊的文件,它也有文件描述符,进程可以打开一个socket,并且像处理文件一样对它进行read()和write()操作,而不必关心数据是怎么在网络上传输的
socket是一个tcp连接的两端,网络层的ip地址唯一标识一台主机,而传输层的协议+端口号可以唯一标识绑定到这个端口的进程
socket编程中listen()和accept()的区别
int listen(int sockfd, int backlog)
摘要:listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。
listen函数在一般在调用bind之后-调用accept之前调用,它的函数原型是:
参数sockfd
被listen函数作用的套接字,sockfd之前由socket函数返回。在被socket函数返回的套接字fd之时,它是一个主动连接的套接字,也就是此时系统假设用户会对这个套接字调用connect函数,期待它主动与其它进程连接,然后在服务器编程中,用户希望这个套接字可以接受外来的连接请求,也就是被动等待用户来连接。由于系统默认时认为一个套接字是主动连接的,所以需要通过某种方式来告诉系统,用户进程通过系统调用listen来完成这件事。
参数backlog
这个参数涉及到一些网络的细节。进程处理一个一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接,这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。
int accept(int s, struct sockaddr * addr, int * addrlen)
服务程序调用accept函数,从处于监听状态的socket的客户连接请求队列中,取出排在最前的一个客户请求,并且创建一个新的套接字来与客户套接字创建连接通道,如果连接成功,就返回新创建的套接字的描述符,以后与客户套接字交换数据的是新创建的套接字;如果失败就返回 INVALID_SOCKET。
该函数的第一个参数指定处于监听状态的流套接字;操作系统利用第二个参数来返回新创建的套接字的地址结构;操作系统利用第三个参数来返回新创建的套接字的地址结构的长度。
listen函数不会阻塞,它只是相当于把socket的属性更改为被动连接,可以接收其他进程的连接。listen侦听的过程并不是一直阻塞,直到有客户端请求连接才会返回,它只是设置好socket的属性之后就会返回。监听的过程实质由操作系统完成。但是accept会阻塞(也可以设置为非阻塞),如果listen的套接字对应的连接请求队列为空(没有客户端连接请求),它会一直阻塞等待。
客户端和服务端的socket有什么区别
一个客户端和一个服务端连接,双方socket产生各自的client_sock_fd和server_sock_fd; server_sock_fd进行bind和listen后,accept准备接受客户端的连接请求;client_sock_fd调用connect请求连接服务端; 服务端接到请求产生accept_fd,届时accept_fd和client_sock_fd两个套接字可以通讯,而server_sock_fd则可以关闭; 客户端关闭close(client_sock_fd)后,服务端关闭所有未关闭的fd,通讯彻底断开。
ps:服务端的socket产生的套接字只是用来监听的,不能直接用于发送接收数据。
socket在内核有buffer,为什么还需要应用层buffer?
没有应用层buffer从哪拷贝到内核buffer呢?
假设我们要通过TCP连接来发送100k的数据,在执行write()时,操作系统受某些因素的影响只接受了80k数据,那么由于还剩20k我们该如何处理?是等待内核腾出空间来接受余下的20k?那如果等很久怎么办?难道我们的事件循要在你的等待时间内什么都做不成么?针对以上的问题我们就可以**用一个应用层的write buffer来解决把那些暂时内核无法接受的数据先存在buffer中,然后注册POLLOUT事件,一旦 socket 变得可写就立刻发送数据,如果下次还写不完那么就继续注册POLLOUT事件下次继续写,如果20k数据已经写完了,立即停止关注POLLOUT事件
####DNS的工作过程和原理
DNS解析有两种方式:递归查询和迭代查询
- 递归查询 用户先向本地域名服务器查询,如果本地域名服务器的缓存没有IP地址映射记录,就向根域名服务器查询,根域名服务器就会向顶级域名服务器查询,顶级域名服务器向权限域名服务器查询,查到结果后依次返回。
- 迭代查询 用户向本地域名服务器查询,如果没有缓存,本地域名服务器会向根域名服务器查询,根域名服务器返回顶级域名服务器的地址,本地域名服务器再向顶级域名服务器查询,得到权限域名服务器的地址,本地域名服务器再向权限域名服务器查询得到结果
HTTP
Keep-Alive
Keep-Alive解决的核心问题是: 一定时间内,同一域名多次请求数据,只建立一次 HTTP 请求,其他请求可复用每一次建立的连接通道,以达到提高请求效率的问题
Keep-Alive还是存在如下问题:
- 串行的文件传输。
- 同域并行请求限制带来的阻塞(6~8)个
Pipeline
HTTP 管线化可以克服同域并行请求限制带来的阻塞,它是建立在持久连接之上,是把所有请求一并发给服务器,但是服务器需要按照顺序一个一个响应,而不是等到一个响应回来才能发下一个请求,这样就节省了很多请求到服务器的时间。不过,HTTP 管线化仍旧有阻塞的问题,若上一响应迟迟不回,后面的响应都会被阻塞到。
多路复用
多路复用代替原来的序列和阻塞机制。所有就是请求的都是通过一个 TCP 连接并发完成。因为在多路复用之前所有的传输是基于基础文本的,在多路复用中是基于二进制数据帧的传输、消息、流,所以可以做到乱序的传输。多路复用对同一域名下所有请求都是基于流,所以不存在同域并行的阻塞。
HTTP请求报文与响应报文格式
请求报文:请求行(包含请求方法、URI、HTTP版本信息);请求首部字段;请求内容实体
响应报文:状态行(包含HTTP版本、状态码及原因短语);响应首部字段;响应内容实体
请求和响应头部后面都要空一行,表示头部内容到此结束
http头包含哪些字段
通用首部字段(请求报文与响应报文都会使用的首部字段) Date:创建报文时间 Connection:连接的管理 Cache-Control:缓存的控制 Transfer-Encoding:报文主体的传输编码方式
请求首部字段(请求报文会使用的首部字段) Host:请求资源所在服务器 Accept:可处理的媒体类型 Accept-Charset:可接收的字符集 Accept-Encoding:可接受的内容编码 Accept-Language:可接受的自然语言
响应首部字段(响应报文会使用的首部字段) Accept-Ranges:可接受的字节范围 Location:令客户端重新定向到的URI Server:HTTP服务器的安装信息
实体首部字段(请求报文与响应报文的的实体部分使用的首部字段) Allow:资源可支持的HTTP方法 Content-Type:实体主类的类型 Content-Encoding:实体主体适用的编码方式 Content-Language:实体主体的自然语言 Content-Length:实体主体的的字节数
状态码
1xx:在处理了
2xx:处理成功
200:请求被正常处理 204:请求成功但没有资源返回
3xx:重定向
301:永久重定向 302:临时重定向
4xx:出问题了
400:请求报文语法有误,服务器无法识别 401:请求需要认证 403:请求的对应资源禁止被访问 404:服务器无法找到对应资源
5xx:服务器挂了
500:服务器内部错误 503:服务器正忙
请求方法
GET:用于请求访问已经被URL(统一资源标识符)识别的资源,可以通过URL传参给服务器。
POST:用于传输信息给服务器,主要功能与Get方法类似,但一般推荐POST方式。
PUT:传输文件,报文主体包含文件内容,保存到对应URL位置。
PATCH:对资源进行部分修改
DELETE:删除文件,与PUT方法相反,删除对应URL位置的文件。
HEAD:获取报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URL是否有效。
OPTIONS:查询相应URL支持的HTTP方法。
get和post的区别
get是从服务器上获取数据,post是向服务器传送数据。
get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是将表单内各个字段与其内容放置在HTML header内一起传送到URL地址。
get传送的数据量较小(受URL限制),post传送的数据量较大
get安全性非常低,因为URL是可见的,post安全性较高,但依然以明文的形式存放于 HTTP 的请求头中。
get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码,post支持标准字符集,可以正确传递中文字符。
get能被缓存,post不能缓存
get历史参数保留在浏览器历史中,post参数不会保存在浏览器历史中
session与cookies区别,以及分别存储在什么地方
HTTP 是一种无状态的连接,客户端每次读取 web页面时,服务器都会认为这是一次新的会话。但有时候我们又需要持久保持某些信息,比如登录时的用户名、密码,用户上一次连接时的信息等。这些信息就由 Cookie 和 Session 保存。
cookie实际上是一小段文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个cookie,客户端浏览器会把cookie保存起来,当浏览器再次请求访问该网站时,浏览器把请求的网站连同该cookie一同提交给服务器,服务器检查该cookie,以此来辨认用户状态。cookie在客户端浏览器上,可能会被伪造不安全
Session以cookie为基础,同一个客户端每次和服务端交互时,不需要每次都传回所有的 Cookie 值,而是只要传回一个 ID,这个 ID 是客户端第一次访问服务器的时候生成的,而且每个客户端是唯一的。这样每个客户端就有了一个唯一的 session id,客户端只要传回这个session id就行了,session数据放在服务器上(访问多的时候吃性能),session cookie在浏览器内存里。session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)。会话结束后session cookie会消失,更加安全
一个网页从输入url到出现渲染画面的整个过程
DNS 解析:将域名解析成 IP 地址(浏览器缓存-操作系统缓存-路由缓存-ISP互联网服务提供商的DNS服务器-根DNS服务器)
TCP 连接:TCP 三次握手(见上)
发送 HTTP 请求
服务器处理请求并返回 HTTP 报文
浏览器解析渲染页面:首先是html文档解析,浏览器会将html文档生成解析树,也就是DOM树,它由dom元素以及属性节点组成。然后浏览器加载过程中如果遇到了外部css文件或者图片资源,还会另外发送请求来获取css文件和资源,这个请求通常是异步的,不会影响html文档的加载。不过如果浏览器在加载时遇到了js文件,则会挂起渲染的线程,等待js文件加载解析完毕才恢复html的渲染线程。然后是css解析,将css文件解析为样式表对象来渲染DOM树。
断开连接:TCP 四次挥手
http与https区别
HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
HTTPS:
混合加密实现信息的机密性,解决了窃听的风险。
数字证书证明服务器公钥可信,解决了冒充的风险。
摘要算法算出明文摘要,校验数据的完整性,解决了篡改的风险。
https原理
- 混合加密
- 数字证书
- 摘要
SSL 提供报文摘要功能来进行完整性保护。
HTTP 也提供了 MD5 报文摘要功能,但不是安全的。例如报文内容被篡改之后,同时重新计算 MD5 的值,通信接收方是无法意识到发生了篡改。
HTTPS 的报文摘要功能之所以安全,是因为它结合了加密和认证这两个操作。试想一下,加密之后的报文,遭到篡改之后,也很难重新计算报文摘要,因为无法轻易获取明文。
为什么对称加密更快
对称加密是分组加密的,把数据分组然后再用密钥加密,而非对称是整个数据加密,所以如果数据量大了,加密解密都要比对称加密慢很多