计算机网络小总结

339 阅读15分钟

导语:计算机网络可以算得上是基础中的基础了,面试中也有可能会遇到,我总结了我最近学习计算机网络的一些心得,希望有读者有帮助

三次握手四级挥手(尽力详细)

所谓三次握手(Three-way Handshake),是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。三次握手的目的是客户端连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号并交换TCP窗口大小信息。
额,我们先来看看什么是TCP滑动窗口

TCP滑动窗口

TCP通过滑动窗口的概念来进行流量控制。 设想在发送端发送数据的速度很快而接收端接收数据很慢的情况下,为了保证数据不丢失,显然需要进行流量控制,协调好通信双方的工作节奏。所谓滑动窗口,可以理解为接收端所能提供的缓冲区的大小。 TCP利用一个滑动窗口来告诉发送端对它所发送的数据能提供多大的缓冲区。 由于窗口由16位bit所定义,所以接收端TCP能最大提供 65535个字节的缓冲

关于滑动窗口还有三个术语

窗口合拢 : 当窗口从左边向右边靠近的时候,这种现象发生在数据被发送和确认的时候 窗口张开:当窗口的右边沿着右边移动的时候,这种现象发生在接收端处理了数据以后。

TCP就是用这个窗口,慢慢的从数据的左边移动到右边,把处于窗口范围内的数据发送出去

三次握手

  • 第一次握手
    客户端发送一个TCP的SYN标志位置1的包 指明客户打算连接的服务器的端口 , 以及初始序列号X , 保存在包头的序列号 (Sequence Number)字段里 SYN = 1 , seq = x
  • 第二次握手
    服务器返回确认包(ACK)应答.即SYN 标志位和 ACK标志位均为1 , 同时将确认序列号 (ACK)设置为 客户的SYN = 1 , ACK = 1 , seq = y , ack = x + 1
  • 第三次握手
    客户端再次发送确认包ACK 为 1 并且把服务器发送来的 ACK = 1 , seq = x + 1 , ack = y + 1

SYN攻击

在三次握手过程中 , 服务器发送 SYN-ACK 之后 , 收到客户端的 ACK之前的 TCP连接称为 半连接 (half-open connect)。此时服务器处于 SYN-RECV状态。当收到 ACK后 , 服务器转入 ESTABLISHED 状态。 SYN攻击就是 攻击客户端 在 短时间内 伪造大量不存在的IP地址, 向服务器不断发送 SYN包 , 服务器回复确认包 , 并等待客户的确认 , 由于原地址不存在 , 服务器需要不断的重复发送直到超时, 这些伪造的SYN包将长时间占用未连接队列mlm正常的SYN 请求被放弃, 直到系统瘫痪。

SYN攻击的一个典型的 DDOS攻击 , 检测 SYN 攻击非常方便 , 主要方法有

  • SynAttackProtect保护机制
  • SYN cookies 技术
  • 增加最大半连接数量
  • 缩短超时时间

四次挥手

TCP的连接拆除需要发送四个包,因此成为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作

  • 第一次挥手. 客户端进程发出连接释放报文, 并且停止发送数据。释放数据报文首部,FIN = 1 , 其序列号为 seq = u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时 , 客户端进入FIN-WAIT-1(终止等待1)状态。TCP规定,FIN报文即使不携带数据,也要消耗一个序号

  • 第二次挥手 服务器收到连接释放报文,发出确认报文,ACK=1,ack= u + 1,并且带上自己的序列号 seq = v, 此时, 就进入了 close-wait(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器如果发送数据,客户端依然要接收。这个状态还要持续一段时间,也就是整个 close-wait 状态持续的时间
    客户端收到服务器的确认请求后,此时,客户端就进入 fin-wait-2 状态,等待服务器发送链接释放报文(在这之前还需要接受服务器发送的最后的数据)

  • 第三次挥手 服务器将最后的数据发送完毕后,就向客户端发送链接释放报文,FIN = 1 ,ack = u + 1 ,由于在半关闭状态,服务器很可能又发送了一些数据,假设此时的序列号为 seq = w ,此时, 服务器就进入了 last-ack(最后确认)状态, 等待客户端的确认。

  • 第四次挥手 客户端收到服务器的连接释放报文后,必须发出确认, ACK = 1 , ack = w + 1, 而自己的序列号是 seq = u + 1, 此时,客户端就进入 time-wait(时间等待)状态。注意:此时 TCP连接还没有释放 , 必须经过 2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才会进入 close状态
    服务器只要收到了客户端发出的确认,立即进入 closed状态
    可以看到,服务器结束TCP连接的时间要比客户端早一些。

三次握手,四级挥手 常见题目

  1. 为什么连接的时候是三次握手,关闭的时候却是四次挥手?
    因为 server端必需发送完所有报文,才会发送 FIN 报文,还有剩余数据要发送。
  2. 为什么 time_wait状态需要经过 2MSL(最大报文段生存时间)才能返回到close状态?
    虽然按道理,四个报文都发送完毕,我们可以直接进入 close 状态了, 但是我们必须假想网络是不可靠的,有可以最后一个ACK失去。所以
    time_wait 状态就是用来重发可能丢失的 ack报文
    在 client 发送出最后的 ACK 回复, 但该 ACK 可能丢失。 Server如果没有收到 ACK , 将不断重复发送 FIN 片段。 所以 Client 不能立即关闭, 它必须确认 Server 接收到了该 ACK。 Client 会在发送出 ACK之后进入到 time_wait 状态。Client 会设置一个计时器 , 等待 2MSL的时间。如果在该时间内再次收到了FIN ,那么 Client 会重发 ACK并再次等待 2MSL。 所谓的 2MSL是两倍 MSL(Maximum Segment Lifetime)。 MSL指的是一个片段在网络中最大的存活时间, 2MSL就是一个发送和一个回复所需要的最大时间。如果直到2MSL, Client都没有再次收到 FIN, 那么 Client 推断 ACK已经被成功接收, 则结束TCP连接。
  3. 为什么不能用两次握手进行连接?
    三次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
    现在把三次握手改成仅需要两次握手,死锁是可能发生的。
    作为例子,考虑计算机 Server 和 Client 之间的通信,假定 Client 给 Server 发送一个连接请求分组 , Server 收到了这个分组 , 并发送了确认应答分组。按照两次握手的协议, Server认为连接已经成功地建立了,可以开始发送数据分组。可是, Client在 Server的应答分组在传输中被丢失的情况下,将不知道 server 是否已经准备好, 不知道 server建立什么样的序列号, client甚至怀疑 server是否收到自己的连接请求分组。这这种情况下, client认为连接还未建立成功,将忽略 server 发来的如何数据分组,只等待连接确认应答分组,只等待连接确认应答分组。而 server在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

Step1       A -> B : 你好,B。
Step2       A <- B : 收到。你好,A。

这样的两次握手过程, A 向 B 打招呼得到了回应,即 A 向 B 发送数据,B 是可以收到的。

但是 B 向 A 打招呼,A 还没有回应,B 没有收到 A 的反馈,无法确保 A 可以收到 B 发送的数据。

对称加密与非对称加密

首先我们先介绍一下密码学,定义很简单,
研究如何隐秘地传递信息的学科

古典加密 凯撒加密算法

凯撒密码是由凯撒大帝在军队中使用来传递信息的算法。通过对 26个 字母进行位移替换加密 , 规则简单, 容易破解。
我们来举个栗子
我们已经知道明文为:
明文 : H E L L O W O R L D (helloworld)
密匙: n = 3
密文: K H O O R Z R U O G
说白了,每个单词向右移动3位,解密就是每个单向左移动三位

对称加密

好的,我们热身结束,来点现代的。其实也挺简单的。
采用对称加密系统的加密方法,同一个密匙可以同时用作信息的加密和解密,这种加密方式称为对称加密,也称为单密匙加密。
经典的对称加密算法:DES,3DES,AES,IDEA
好的,我们来仔细的介绍一下 DES

对称加密的优缺点

  • 优点: 对称加密算法的优点是算法公开,计算量小,加密速度快
  • 缺点: 对称加密算法的缺点也很明显,那就是如果在传输过程中,如果一方的密匙被泄漏了,那么加密后的信息也和没有加密一样,不安全了

非对称加密

非对称加密算法需要两个密匙: 公开密钥和 私有密钥。公开密钥与私有密钥是一对, 只有同时拥有 两个密钥 , 才能对密文进行解密。至于 公匙和私匙是怎么被创建出来的?那就是加密算法该做的事情了。典型的非对称加密算法有 RSA 和 ECC(椭圆曲线算法)。
下面简要的介绍一下 RSA 公钥加密算法

RSA 加密算法(大概介绍)

RSA 算法是最著名的公钥密码算法。其安全性是建立在 大数因子分解 这一已知的数论难题的基础上 , 即将两个大质数相乘在计算上很容易实现 , 但将该乘积分解为 两个大质数因子的 计算量则是相当巨大的 , 以至于在实际计算中不能实现。
我们来应用 RSA 举个栗子

明文为 : "HI" , 操作过程如下:
一. 设计密钥 公钥 e , 和 私钥 d 
1. 我们先找两个质数(我们找小一点的,方便计算),p = 11 , q = 5
2. 将两个质数相乘  n = p x q = 55;
3. 计算欧拉函数 φ(n) = (p-1)(q-1) = 40;(不要问我欧拉函数是啥,我也不知道)
4.计算公钥 e = 3 (  1 < e < φ(n) )(随机)
5.接下来我们计算私钥 d , e * d % φ(n) = 1 , 我们得到 d = 27(私钥) 。
6. 现在我们拥有 公钥 (e , n)  和 私钥 ( d , n ) , 我们看可以加密了

二. 加密。(我们按 1 - 26 的次序排序字母 , 则 H为 8, I 为 9)
1. 用 公钥 (3,55)加密 : E(H) = 8^e mod n = 17 ; 
E(I) = 9^e mod n = 14; (17 为 Q , 14 为 N )。

加密后明文为:  "QN"
2. 解密。 D(Q) = 17^d mod n , D(N)= 14^d mod n , 解得 Q == 8 , N = 9。

RSA算法的工作原理如下: 假设用户 A 要发送消息 m 给用户 B , 则 RSA算法的加密/解密过程如下:

  1. 首先, B 产生两个大质数p 和 q (p , q 是保密的)
  2. B计算 n = pq 和 φ(n)= (p-1)(q-1) (φ(n)是保密的)
  3. B 选择一个随机数 e (0<e<φ(n))
  4. B 计算得出 d , 使得 d x e mod φ(n) =1 。 私钥是 d , B自留并且保密
  5. A 通过公开信道查到 n 和 e。对 m 加密。 E(m) = m^e mod n;
  6. B 收到密文 c 后 , 解密 D (c) = c^d mod n;

数字证书

上面非对称加密,似乎很完美的解决了安全问题。那么这中间真的不存在漏洞吗?这时候,我们想一下所谓的中间人攻击
例如:
服务器以明文的方式给客户端传输公钥的时候,中间人截取了这把属于服务器的公钥,并且把中间人自己的公钥冒充服务器的公钥传输给了客户端。之后客户端就会用中间人的公钥来加密自己生成的密钥。然后把被加密的密钥传输给服务器,这个时候中间人又把密钥给截取了,中间人用自己的私钥对这把被加密的密钥进行解密,解密后中间人就可以获得这把密钥了。 最后中间人再对这把密钥用刚才服务器的公钥进行加密,再发送给服务器。
毫无疑问,在这个过程中,中间人获取了对称加密中的密钥,在之后服务器和客户端的对称加密传输中,这些加密的数据对中间人来说,和明文没有任何区别。
我们知道,非对称加密之所以不安全,是因为客户端不知道这把公钥是不是属于服务器的

数字证书介绍

在上面的介绍中,我们知道,之所以非对称加密是不安全的,是因为客户端不知道这把公钥是否是服务器的,因此,我们需要找到一种策略来证明这把公钥就是服务器的,而不是别人冒充的。
解决这个问题的方式就是使用数字证书。 我们需要一个所有人都认可的 认证中心(CA)
服务器在给客户端传输公钥的过程中,会把公钥以及服务器的个人信息通过 hash算法生成信息摘要,为了防止信息摘要被人调换,服务器还会用 CA提供的私钥对信息摘要进行加密来形成数字签名,并且,最后还会把原来没有 hash算法之前的个人信息以及公钥 和 数字签名合并在一起 , 形成数字证书
当客户端拿到这份数字证书之后,就会用CA提供的公钥来对数字证书里面的数字签名进行解密来得到信息摘要,然后对数字证书里服务器的公钥以及个人信息进行 hash 得到 另外一份信息摘要 。最后
把两份信息摘要进行对比
,如果一样,则证明这个人是服务器,否则不是。这样,就可以保证服务器的公钥安全地交给客户端了

https的工作流程

我们知道 , 非对称加密在性能上不如对称加密, 拿是否能将两者结合起来呢?例如 , 非对称加密主要用于传输对称加密的秘钥,而真正的双方大数据量的通信都是通过对称加密进行的。

  • 由于是https, 客户端会发送 Client Hello 消息到服务器 , 以明文传输 TLS版本消息,加密套件候选列表, 压缩算法候选列表等消息。另外, 还会有一个随机数,在协商对称密钥的时候使用
  • Server Hello 消息, 告诉客户端 , 服务器选择使用的协议版本,加密套件, 压缩算法等,还有一个随机数 , 用于后续的密钥协商
  • 银行网站会给你一个服务器端的证书
  • 客户端从自己信任的CA仓库中 , 拿CA的证书里面的公钥取解密银行网站的证书。如果能够成功,则说明银行网站是可信的。这个过程中,你可能会不断从上追溯CA,CA的CA,直到一个授权的CA,便可以了
  • 证书验证完毕之后,觉得这个银行网站可信,于是客户端计算产生随机数字 Pre-master,用证书中的公钥加密,再发生给服务器,服务器可以通过私钥解密出来。
  • 到目前为止, 无论是客户端还是服务器,都有了三个随机数,分布式 : 自己的 , 对端的 , 以及刚生成的 Pre-master 随机数。通过这三个随机数 , 可以在客户端和服务器产生相同的对称密钥
  • 有了对称密钥
  • 当双方握手结束之后,就可以通过对称密钥进行加密传输了