wireshark抓取tcp三次握手(wireshark抓取tcp报文)

      最后更新:2024-02-18 08:45

      如何查看wireshark抓取TCP三次握手后的连接状态图?

      可以试试基于进程抓包的QPA软件分析,详情 http://jingyan.baidu.com/article/c33e3f48aefa58ea15cbb58d.html
      如何查看wireshark抓取TCP三次握手后的连接状态图?

      TCP协议详解及实战解析【精心整理收藏】

      TCP协议是在TCP/IP协议模型中的运输层中很重要的一个协议、负责处理主机端口层面之间的数据传输。主要有以下特点:1.TCP是面向链接的协议,在数据传输之前需要通过三次握手建立TCP链接,当数据传递完成之后,需要通过四次挥手进行连接释放。2.每一条TCP通信都是两台主机和主机之间的,是点对点传输的协议。3.TCP提供可靠的、无差错、不丢失、不重复,按序到达的服务。4.TCP的通信双方在连接建立的任何时候都可以发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据。5.面向字节流。在数据传输的过程中如果报文比较长的话TCP会进行数据分段传输,每一条分段的TCP传输信息都带有分段的序号,每一段都包含一部分字节流。接收方根据每段携带的的序号信息进行数据拼接,最终拼接出来初始的传输数据。但是在整个传输的过程中每一段TCP携带的都是被切割的字节流数据。所以说TCP是面向字节流的。a.TCP和UDP在发送报文时所采用的方式完全不同。TCP并不关心应用程序一次把多长的报文发送到TCP缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP发送的报文长度是应用程序给出的)。b.如果应用程序传送到TCP缓存的数据块太大,TCP就可以把它划分短一些再传。TCP也可以等待积累有足够多的字节后再构建成报文段发送出去。各字段含义:源端口:发送端的端口号目的端口:接收端的端口号序号:TCP将发送报文分段传输的时候会给每一段加上序号,接收端也可以根据这个序号来判断数据拼接的顺序,主要用来解决网络报乱序的问题确认号:确认号为接收端收到数据之后进行排序确认以及发送下一次期待接收到的序号,数值 = 接收到的发送号 + 1数据偏移:占4比特,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定,因此数据偏移字段是必要的。数据偏移以32位为长度单位,因此TCP首部的最大长度是60(15*4)个字节。控制位:URG:此标志表示TCP包的紧急指针域有效,用来保证TCP连接不被中断,并且督促 中间层设备要尽快处理这些数据;ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1, 为1的时候表示应答域有效,反之为0;PSH:这个标志位表示Push操作。所谓Push操作就是指在数据包到达接收端以后,立即传送给应用程序, 而不是在缓冲区中排队;RST:这个标志表示连接复位请求。用来复位那些产生错误的连接,也被用来拒绝错误和非法的数据包;SYN:表示同步序号,用来建立连接。SYN标志位和ACK标志位搭配使用,当连接请求的时候,SYN=1, ACK=0;连接被响应的时候,SYN=1,ACK=1;这个标志的数据包经常被用来进行端口扫描。扫描者发送 一个只有SYN的数据包,如果对方主机响应了一个数据包回来 ,就表明这台主机存在这个端口;但是由于这 种扫描方式只是进行TCP三次握手的第一次握手,因此这种扫描的成功表示被扫描的机器不很安全,一台安全 的主机将会强制要求一个连接严格的进行TCP的三次握手;FIN: 表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了,发送FIN标志 位的TCP数据包后,连接将被断开。这个标志的数据包也经常被用于进行端口扫描。窗口:TCP里很重要的一个机制,占2字节,表示报文段发送方期望接收的字节数,可接收的序号范围是从接收方的确认号开始到确认号加上窗口大小之间的数据。后面会有实例讲解。校验和:校验和包含了伪首部、TCP首部和数据,校验和是TCP强制要求的,由发送方计算,接收方验证紧急指针:URG标志为1时,紧急指针有效,表示数据需要优先处理。紧急指针指出在TCP段中的紧急数据的最后一个字节的序号,使接收方可以知道紧急数据共有多长。选项:最常用的选项是最大段大小(Maximum Segment Size,MSS),向对方通知本机可以接收的最大TCP段长度。MSS选项只在建立连接的请求中发送。放在以太网帧里看TCP的位置TCP 数据包在 IP 数据包的负载里面。它的头信息最少也需要20字节,因此 TCP 数据包的最大负载是 1480 - 20 = 1460 字节。由于 IP 和 TCP 协议往往有额外的头信息,所以 TCP 负载实际为1400字节左右。因此,一条1500字节的信息需要两个 TCP 数据包。HTTP/2 协议的一大改进, 就是压缩 HTTP 协议的头信息,使得一个 HTTP 请求可以放在一个 TCP 数据包里面,而不是分成多个,这样就提高了速度。以太网数据包的负载是1500字节,TCP 数据包的负载在1400字节左右一个包1400字节,那么一次性发送大量数据,就必须分成多个包。比如,一个 10MB 的文件,需要发送7100多个包。发送的时候,TCP 协议为每个包编号(sequence number,简称 SEQ),以便接收的一方按照顺序还原。万一发生丢包,也可以知道丢失的是哪一个包。第一个包的编号是一个随机数。为了便于理解,这里就把它称为1号包。假定这个包的负载长度是100字节,那么可以推算出下一个包的编号应该是101。这就是说,每个数据包都可以得到两个编号:自身的编号,以及下一个包的编号。接收方由此知道,应该按照什么顺序将它们还原成原始文件。收到 TCP 数据包以后,组装还原是操作系统完成的。应用程序不会直接处理 TCP 数据包。对于应用程序来说,不用关心数据通信的细节。除非线路异常,否则收到的总是完整的数据。应用程序需要的数据放在 TCP 数据包里面,有自己的格式(比如 HTTP 协议)。TCP 并没有提供任何机制,表示原始文件的大小,这由应用层的协议来规定。比如,HTTP 协议就有一个头信息Content-Length,表示信息体的大小。对于操作系统来说,就是持续地接收 TCP 数据包,将它们按照顺序组装好,一个包都不少。操作系统不会去处理 TCP 数据包里面的数据。一旦组装好 TCP 数据包,就把它们转交给应用程序。TCP 数据包里面有一个端口(port)参数,就是用来指定转交给监听该端口的应用程序。应用程序收到组装好的原始数据,以浏览器为例,就会根据 HTTP 协议的Content-Length字段正确读出一段段的数据。这也意味着,一次 TCP 通信可以包括多个 HTTP 通信。服务器发送数据包,当然越快越好,最好一次性全发出去。但是,发得太快,就有可能丢包。带宽小、路由器过热、缓存溢出等许多因素都会导致丢包。线路不好的话,发得越快,丢得越多。最理想的状态是,在线路允许的情况下,达到最高速率。但是我们怎么知道,对方线路的理想速率是多少呢?答案就是慢慢试。TCP 协议为了做到效率与可靠性的统一,设计了一个慢启动(slow start)机制。开始的时候,发送得较慢,然后根据丢包的情况,调整速率:如果不丢包,就加快发送速度;如果丢包,就降低发送速度。Linux 内核里面 设定 了(常量TCP_INIT_CWND),刚开始通信的时候,发送方一次性发送10个数据包,即"发送窗口"的大小为10。然后停下来,等待接收方的确认,再继续发送。默认情况下,接收方每收到 两个TCP 数据包,就要 发送 一个确认消息。"确认"的英语是 acknowledgement,所以这个确认消息就简称 ACK。ACK 携带两个信息。发送方有了这两个信息,再加上自己已经发出的数据包的最新编号,就会推测出接收方大概的接收速度,从而降低或增加发送速率。这被称为"发送窗口",这个窗口的大小是可变的。注意,由于 TCP 通信是双向的,所以双方都需要发送 ACK。两方的窗口大小,很可能是不一样的。而且 ACK 只是很简单的几个字段,通常与数据合并在一个数据包里面发送。即使对于带宽很大、线路很好的连接,TCP 也总是从10个数据包开始慢慢试,过了一段时间以后,才达到最高的传输速率。这就是 TCP 的慢启动。TCP 协议可以保证数据通信的完整性,这是怎么做到的?前面说过,每一个数据包都带有下一个数据包的编号。如果下一个数据包没有收到,那么 ACK 的编号就不会发生变化。举例来说,现在收到了4号包,但是没有收到5号包。ACK 就会记录,期待收到5号包。过了一段时间,5号包收到了,那么下一轮 ACK 会更新编号。如果5号包还是没收到,但是收到了6号包或7号包,那么 ACK 里面的编号不会变化,总是显示5号包。这会导致大量重复内容的 ACK。如果发送方发现收到 三个 连续的重复 ACK,或者超时了还没有收到任何 ACK,就会确认丢包,即5号包遗失了,从而再次发送这个包。通过这种机制,TCP 保证了不会有数据包丢失。TCP是一个滑动窗口协议,即一个TCP连接的发送端在某个时刻能发多少数据是由滑动窗口控制的,而滑动窗口的大小实际上是由两个窗口共同决定的,一个是接收端的通告窗口,这个窗口值在TCP协议头部信息中有,会随着数据的ACK包发送给发送端,这个值表示的是在接收端的TCP协议缓存中还有多少剩余空间,发送端必须保证发送的数据不超过这个剩余空间以免造成缓冲区溢出,这个窗口是接收端用来进行流量限制的,在传输过程中,通告窗口大小与接收端的进程取出数据的快慢有关。另一个窗口是发送端的拥塞窗口(Congestion window),由发送端维护这个值,在协议头部信息中没有,滑动窗口的大小就是通告窗口和拥塞窗口的较小值,所以拥塞窗口也看做是发送端用来进行流量控制的窗口。滑动窗口的左边沿向右移动称为窗口合拢,发生在发送的数据被确认时(此时,表明数据已被接收端收到,不会再被需要重传,可以从发送端的发送缓存中清除了),滑动窗口的右边沿向右移动称为窗口张开,发生在接收进程从接收端协议缓存中取出数据时。随着发送端不断收到的被发送数据的ACK包,根据ACK包中的确认序号和通告窗口大小使滑动窗口得以不断的合拢和张开,形成滑动窗口的向前滑动。如果接收进程一直不取数据,则会出现0窗口现象,即滑动窗口左边沿与右边沿重合,此时窗口大小为0,就无法再发送数据。在TCP里,接收端(B)会给发送端(A)报一个窗口的大小,叫Advertised window。1.在没有收到B的确认情况下,A可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。2.发送窗口里面的序号表示允许发送的序号。显然,窗口越大,发送方就可以在收到对方确认之前连续发送更多数据,因而可能获得更高的传输效率。但接收方必须来得及处理这些收到的数据。3.发送窗口后沿的后面部分表示已发送且已收到确认。这些数据显然不需要再保留了。4.发送窗口前沿的前面部分表示不允许发送的,应为接收方都没有为这部分数据保留临时存放的缓存空间。5.发送窗口后沿的变化情况有两种:不动(没有收到新的确认)和前移(收到了新的确认)6.发送窗口前沿的变化情况有两种:不断向前移或可能不动(没收到新的确认)TCP的发送方在规定时间内没有收到确认就要重传已发送的报文段。这种重传的概念很简单,但重传时间的选择确是TCP最复杂的问题之一。TCP采用了一种自适应算法,它记录一个报文段发出的时间,以及收到响应的确认的时间这两个时间之差就是报文段的往返时间RTT。TCP保留了RTT的一个加权平均往返时间。超时重传时间RTO略大于加权平均往返时间RTT:即Round Trip Time,表示从发送端到接收端的一去一回需要的时间,tcp在数据传输过程中会对RTT进行采样(即对发送的数据包及其ACK的时间差进行测量,并根据测量值更新RTT值,具体的算法TCPIP详解里面有),TCP根据得到的RTT值更新RTO值,即Retransmission TimeOut,就是重传间隔,发送端对每个发出的数据包进行计时,如果在RTO时间内没有收到所发出的数据包的对应ACK,则任务数据包丢失,将重传数据。一般RTO值都比采样得到的RTT值要大。如果收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据?答案是可以的,选择确认就是一种可行的处理方法。如果要使用选项确认SACK,那么在建立TCP连接时,就要在TCP首部的选项中加上“允许SACK”的选项,而双方必须都事先商定好。如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。SACK文档并没有明确发送方应当怎么响应SACK.因此大多数的实现还是重传所有未被确认的数据块。一般说来,我们总是希望数据传输的更快一些,但如果发送方把数据发送的过快,接收方就可能来不及接收,这会造成数据的丢失。所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。在计算机网络中的链路容量,交换节点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞。拥塞控制方法:1.慢开始和拥塞避免2.快重传和快恢复3.随机早期检测1.一开始,客户端和服务端都处于CLOSED状态2.先是服务端主动监听某个端口,处于LISTEN状态(比如服务端启动,开始监听)。3.客户端主动发起连接SYN,之后处于SYN-SENT状态(第一次握手,发送 SYN = 1 ACK = 0 seq = x ack = 0)。4.服务端收到发起的连接,返回SYN,并且ACK客户端的SYN,之后处于SYN-RCVD状态(第二次握手,发送 SYN = 1 ACK = 1 seq = y ack = x + 1)。5.客户端收到服务端发送的SYN和ACK之后,发送ACK的ACK,之后处于ESTABLISHED状态(第三次握手,发送 SYN = 0 ACK = 1 seq = x + 1 ack = y + 1)。6.服务端收到客户端的ACK之后,处于ESTABLISHED状态。(需要注意的是,有可能X和Y是相等的,可能都是0,因为他们代表了各自发送报文段的序号。)TCP连接释放四次挥手1.当前A和B都处于ESTAB-LISHED状态。2.A的应用进程先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。3.B收到连接释放报文段后即发出确认,然后B进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时TCP连接处于半关闭状态,即A已经没有数据发送了。从B到A这个方向的连接并未关闭,这个状态可能会持续一些时间。4.A收到来自B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文端。5.若B已经没有向A发送的数据,B发出连接释放信号,这时B进入LAST-ACK(最后确认)状态等待A的确认。6.A再收到B的连接释放消息后,必须对此发出确认,然后进入TIME-WAIT(时间等待)状态。请注意,现在TCP连接还没有释放掉,必须经过时间等待计时器(TIME-WAIT timer)设置的时间2MSL后,A才进入CLOSED状态。7。B收到A发出的确认消息后,进入CLOSED状态。以请求百度为例,看一下三次握手真实数据的TCP连接建立过程我们再来看四次挥手。TCP断开连接时,会有四次挥手过程,标志位是FIN,我们在封包列表中找到对应位置,理论上应该找到4个数据包,但我试了好几次,实际只抓到3个数据包。查了相关资料,说是因为服务器端在给客户端传回的过程中,将两个连续发送的包进行了合并。因此下面会按照合并后的三次挥手解释,若有错误之处请指出。第一步,当主机A的应用程序通知TCP数据已经发送完毕时,TCP向主机B发送一个带有FIN附加标记的报文段(FIN表示英文finish)。第二步,主机B收到这个FIN报文段之后,并不立即用FIN报文段回复主机A,而是先向主机A发送一个确认序号ACK,同时通知自己相应的应用程序:对方要求关闭连接(先发送ACK的目的是为了防止在这段时间内,对方重传FIN报文段)。第三步,主机B的应用程序告诉TCP:我要彻底的关闭连接,TCP向主机A送一个FIN报文段。第四步,主机A收到这个FIN报文段后,向主机B发送一个ACK表示连接彻底释放。这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。原因有二:一、保证TCP协议的全双工连接能够可靠关闭二、保证这次连接的重复数据段从网络中消失先说第一点,如果Client直接CLOSED了,那么由于IP协议的不可靠性或者是其它网络原因,导致Server没有收到Client最后回复的ACK。那么Server就会在超时之后继续发送FIN,此时由于Client已经CLOSED了,就找不到与重发的FIN对应的连接,最后Server就会收到RST而不是ACK,Server就会以为是连接错误把问题报告给高层。这样的情况虽然不会造成数据丢失,但是却导致TCP协议不符合可靠连接的要求。所以,Client不是直接进入CLOSED,而是要保持TIME_WAIT,当再次收到FIN的时候,能够保证对方收到ACK,最后正确的关闭连接。再说第二点,如果Client直接CLOSED,然后又再向Server发起一个新连接,我们不能保证这个新连接与刚关闭的连接的端口号是不同的。也就是说有可能新连接和老连接的端口号是相同的。一般来说不会发生什么问题,但是还是有特殊情况出现:假设新连接和已经关闭的老连接端口号是一样的,如果前一次连接的某些数据仍然滞留在网络中,这些延迟数据在建立新连接之后才到达Server,由于新连接和老连接的端口号是一样的,又因为TCP协议判断不同连接的依据是socket pair,于是,TCP协议就认为那个延迟的数据是属于新连接的,这样就和真正的新连接的数据包发生混淆了。所以TCP连接还要在TIME_WAIT状态等待2倍MSL,这样可以保证本次连接的所有数据都从网络中消失。硬件速度网络和服务器的负载请求和响应报文的尺寸客户端和服务器之间的距离TCP 协议的技术复杂性TCP 连接建立握手;TCP 慢启动拥塞控制;数据聚集的 Nagle 算法;用于捎带确认的 TCP 延迟确认算法;TIME_WAIT 时延和端口耗尽。介绍完毕,就这?是的,就这。补充:大部分内容为网络整理,方便自己学习回顾,参考文章:TCP 协议简介TCP协议图文详解什么是TCP协议?wireshark抓包分析——TCP/IP协议TCP协议的三次握手和四次挥手TCP协议详解TCP带宽和时延的研究(1)
      TCP协议详解及实战解析【精心整理收藏】

      用wireshark在电脑上抓的TCP的三次握手的包

      1)sourcedestination就是ip地址。发SYN的是客户端,客户端一般发起主动连接。 2)菜单项里面有个follow tcp什么的选项,自己看一下就好了。再结合wiki上提到的三次握手。
      用wireshark在电脑上抓的TCP的三次握手的包

      wireshark抓包三次握手怎么判断有问题

      finack指的是数据已经传完了,可以断开连接,如果你仔细观察的话,可以看到最后有两个finack的。pshack都是tcp的头部字段,psh指的是不用在等待其他包了,自己就可以单独发送,所以带有pshack的是数据发送的包,传的应该就是你要的数据,当然到底是不是要看源和目的的ip对不对。
      第一次握手数据包 客户端发送一个TCP,标志位为SYN,序列号为0, 代表客户端请求建立连接。第二次握手的数据包服务器发回确认包, 标志位为 SYN,ACK. 将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即0+1=1。第三次握手的数据包 客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1。
      wireshark抓包三次握手怎么判断有问题

      Wireshark 抓包理解 HTTPS 请求流程

      目录我的操作是这样的,让手机和电脑在同一个局域网内(比如连接同一个 wifi),接着在手机的wifi上设置代理,电脑使用 Charles 做代理,IP 为电脑在局域网 IP,我这边的环境,手机 IP 为 172.17.32.117,电脑 IP 为 172.17.32.19。再设置代理端口为 8888。设置代理后,接下来手机的请求都会通过电脑的网卡代理请求发送出去。其实可以不用这么绕。我之所以多设了一个代理,是因为自己电脑创建的 wifi 热点,手机接收不到。为了让手机的包能经过电脑网络嗅探到才这么处理的。最便捷的方式,就是电脑放个 wifi 热点给手机连接完事。创建后代理连接后,然后使用 Wireshark 嗅探网卡,比如我这里使用的是 etho0 网卡去访问网络的。这时候玩玩手机,打开几个请求,Wireshark 上面就会出现捕捉的大量的包,各种各样的协议都有,有 ARP 寻人启事(寻找 IP 对应的物理地址),有 TCP 连接包,有 HTTP 请求包。这里我设置了一下过滤规则,把对网易的一个https://nex.163.com的一个的请求过滤出来如下:整个完整的 HTTPS 请求的过程如下:接下来把手机称为 A(172.17.32.211),电脑称为 B(172.17.32.19),对完整的过程进行简要分析。作为整个过程的第一个 TCP 包,这里对它做一个详细的剖析,理解一下 TCP 报文的格式和内容。TCP 是传输层协议,负责可靠的数据通信,它在整个体系结构的位置如下:作为传输层协议,主要为上层协议提供三个功能:TCP 协议为 HTTP 和 SSL 协议提供了基础的通信功能。所以 SSL 协议是基于 TCP 的。三次握手的内容有:对每个包进行详细的分析:A 发出一个带 SYN 同步位的包,通知服务端要建立连接。第一次握手,发出的 TCP 包的数据和 Wireshark 解析的结果如下:灰色部分就是 TCP 报文的数据内容,第一个两个字节 0x8c85 = 35973 表示源端口。TCP 报文的格式如下,对应的如上图的灰色部分。非灰色部分分别为 IP 首部和数据帧首部。参考谢希仁版本的 《计算机网络》一书,对照着整个报文格式表,把整个 TCP 报文的二进制信息和相关意义做些说明:到这里的话,TCP 数据报首部固定部分结束,固定部分一共有 20 字节。也就是 TCP 首部,至少要有 20 字节。固定首部后,就是可长度可以变化的选项了:整个所以 TCP 数据包的大小可以这样表示:我们 Wireshark 后面的一长串的信息就指出了该 TCP 报文的一些主要信息:从上面的分析可以看出,这个 SYN 包并没有携带数据,但是按协议这里要消耗一个序号。在发出 SYN 包后,A 端进入SYN-SENT状态。B 收到 SYN 包,发出 SYN + ACK 确认包。这个包,既是确认收到了第一次握手的包,也是一个由 B 端发出的同步包,表示自己准备好了,可以开始传数据了。TCP 报文包相对于第一次握手的包可以窥见一些变化:可以看到,这个包的应答时间戳刚好是第一次握手的发送时间戳。从这里也可以理解到,这个包就是在响应第一次握手的包所以,接收方 A 可以利用这个值来计算这一次RTT,收到第二次握手的包后,计算当前时间戳减去该包的应答时间戳就是一个RTT的延时了。这虽然是 ACK 包,但也是 SYN 包,所以也要消耗一个序号。在发出这个包后,B 端进入 SYN-REVD 状态。A 收到后,再发出一个 ACK 确认包发出的包如下:这里我们产生一个疑问,这里发送端 A 发连接请求信息、接收端 B 发确认信息,又互相同步了序号,是不是已经可以传输数据了?但实际上 A 还要再发一个 ACK 确认报文,如图所示,确认收到了 B 第二次握手发出的包,这个时候,在这个 ACK 包后 A 和 B 才正式进入 ESTABLISHED 状态。这就是第三次握手。这是为什么呢?假设我们用两次握手,然后在第一次握手期间,A 发了第一次握手包后出现了这样的场景:一直没有得到响应而进行超时重传,又发了一次包,然后我们称上一次包为失效包。然后我们可以看到:所以,只有接收端 B 在发送端 A 发出了第三次握手包后,才认为连接已经建立,开始等待发送端 A 发送的数据,才不会因为失效的连接请求报文导致接收端异常。TCP 三次握手的时序图如下:三次握手,有几个重要的任务,一个是同步序号,接收端和发送端都发出同步包来通知对方初始序号,这样子后面接收的包就可以根据序号来保证可靠传输;另一个是让发送端和接收都做好准备。然后就开始传数据了。整个过程都发生在 HTTP 报文发出之前。HTTP 协议就是依靠着 TCP 协议来做传输的管理。TCP 可以认为是它的管家,管理着传输的大大小小的事务,比如要不要保证包顺序一致?什么时候发包?要不要收包?TCP 是很严格的。三次握手在 Java API 层面,对应的就是 Socket 的连接的创建(最终调用的是 native 层的 socket 创建):这里的 connectTimeout 对应的是三次握手的总时长,如果超时了就会被认为连接失败。比如一个场景,客户端发出一个 SYN 报文后,迟迟没有收到服务端的 SYN + ACK。这时候客户端触发重传机制,每次重传的间隔时间加倍,同样没有收到包。然后如果这段时间超出了连接超时时间的设置,那么建立连接超时就发生了。所以,如果三次握手要花的时间,总是大于这里的 connectTimeout 时间,这个 Socket 就无法建立连接。我们这一次请求的三次握手时间在 180ms 左右。像在 OkHttp 中,如果是三次握手阶段的连接超时,是会有重试机制的。也就是重新建联,重新发出 SYN 报文发起 TCP 连接。重新建联的时候会更换连接的路由,如果已经没有可选择路由的话,那么这个就真的失败了。在 OkHttp 3.9.0 的默认配置中,连接超时的时间为 10000ms = 10s。在 OkHttpClient.Builder 中。实际应用的时候,根据业务场景来调整。这次请求,为了让 Wireshark 抓到手机的包,我使用了电脑作为代理。其实就是客户端 A 使用 HTTP 协议和代理服务器 B 建立连接。和普通的 HTTP 请求一样,需要携带 IP + 端口号,如果有身份验证的时候还会带上授权信息,代理服务器 B 会使用授权信息进行验证。然后代理服务器会去连接远程主机,连接成功后返回 200。Wireshark 抓到的包有这样两条信息,就是在创建代理:请求报文:响应报文:HTTP CONNECT 是在 HTTP1.1 新增的命令,用于支撑 https 加密。因为我采用代理的方式抓包才有这一个步骤。如果是直接抓 PC 机上浏览器发出的 HTTPS 包,不会有这个过程。然后我们思考一下,为什么代理服务器需要这些信息,要连接的主机名和端口号?这是因为后面进行 SSL 加密 HTTP协议,因为代理服务器拿不到加密密钥,是无法获取到 HTTP 首部的,进而无法这个请求是要发到哪个主机的。所以,这里先使用 CONNECT 方法,把主机名和对应的端口号通知代理服务器。这个也被称为 HTTPS SSL 隧道协议。建立这个 SSL 隧道后,这个特殊代理就会对数据进行盲转发。SSL 整个协议实际上分两层,SSL 记录协议和其他子协议(SSL握手协议,SSL改变密码协议,SSL警告协议):这两层协议的关系,其实就是数据封装的关系,SSL 握手封装协议封装其他上层协议。封装握手协议:封装应用数据协议,比如 HTTP:封装交换密码协议:封装警报协议:所以 SSL 记录协议其实就是一个其他协议的载体,只是提供了一个封装的功能。它的格式为:MAC 就是消息验证码,用来验证数据的完整性,保证中途没有篡改。这个消息验证码比数字签名弱一些,使用的是对称密钥加密摘要。数字签名使用的是非对称密钥加密,有区分公钥私钥。记录协议的主要目的有这几个,为其他 SSL 子协议提供了以下服务:TCP 三次握手结束并且和代理服务器成功连接后,建联成功,客户端 A 就开始发起 SSL 连接,首先会进入 SSL 握手阶段。SSL 握手阶段的主要目的有这么几个:SSL 握手的流程并不是一成不变的,根据实际的应用场景来。主要有三种:SSL 握手的完整的交互过程如下,这里是验证服务端又验证了客户端的情况:我们的请求只验证服务端,所以 7,8,9 是不存在的。现在具体分析每一个阶段的内容。Client Hello作为 SSL 握手的第一个握手包,我们详细分析和理解一下包的内容。下面是 Wireshark 解析好的这个 SSL 协议的数据包:这个包如何解读,按照之前对 SSL 协议的分析,其实分成两个部分:因为是握手过程,密钥还没协商,这里还是使用明文传输,记录协议的数据载体就是明文的 SSL 握手协议。SSL 握手协议的格式为:我们可以从握手协议的数据包中得到这些信息:密码套件随着密码学的发展而发展,而且根据现实应用中,可能会有某些密码被破解,从而导致密码套件可能会导致安全问题,所以一般都会使用当前最新最安全的密码套件。在 Android 系统中,一般情况下,使用 SSLSocket进行连接的时候,会带上系统默认的支持的密码套件。但是这个有个缺点,比如某些密码套件的加密算法被破解或者出现安全漏洞,而且要跟着系统升级反应缓慢。OkHttp 在进行 SSL 握手的时候,会使用 ConnectionSpec 类中带上提供了一系列最新的密码套件。可以从注释上看,这些密码套件在 Chrome 51 和 Android 7.0 以上得到了完全支持。然后,再把这些密码套件和 Android 系统支持的密码套件取交集,提交给服务端。这样,万一哪个密码套件有问题,OkHttp 官方会下降支持。网络库 OkHttp 库会随着版本的迭代,不断地去提供比较新的密码套件,并且放弃那些不安全的密码套件。接入应用即时更新 OkHttp,就不用等待缓慢的系统更新了。如果提供的所有密码套件服务端都不支持,OkHttp 有回退机制,退而求其次,选比较旧的套件。Server Hello服务端收到了客户端的 Hello,通过客户端的配置信息,结合服务端的自身情况,给出了最终的配置信息。Wireshark 解析后的内容如下:具体内容如下:Certificate上面的 Server Hello 已经制定了接下来的非对称加密算法服务端下发证书,客户端验证服务端的身份,并且取出证书携带的公钥,这个公钥是交换加密算法的公钥。也就是在 Server Hello 阶段指定的ECDHE(EC Diffie-Hellman)算法,也是通常说的 DH 加密。这个 Certificate 消息下发了从携带自己公钥的数字证书和 CA 证书的证书链,在 Certificates 字段中:CA 是 PKI 体系的重要组成部分,称为认证机构。那什么是 CA 证书?就是用来 CA 中心发布的,认证该服务单证书的合法性,可以确保该证书来源可靠而不是被中间人替换了。但是 CA 证书也可能被中间人拦截造假?那就再用一个证书来认证它。看起来好像没完没了。实际上到最后有一个根 CA 证书,这个证书存储再浏览器或者操作系统中,是系统直接信任的。服务端证书需要 CA 证书做认证。使用的还是数字签名方式,从数据中摘要一段信息,用 CA 证书的加密。然后验证的时候时候,用 CA 证书的公钥解密,用同样的摘要算法摘要数据部分和解密好的信息进行比较。客户端在验证服务端证书的有效性有这样的一个过程。首先会找到该证书的认证证书,也就是中级 CA 证书。然后找中级 CA 证书的认证证书,可以是另一个中级 CA 证书,也可能是根 CA 证书。这样直到根 CA 证书。接着从根 CA 证书开始往下去验证数字签名。比如有这样的证书链:根 CA 证书-> 中级 CA 证书 -> 服务端证书。用 CA 证书的公钥去验证中级证书的数字签名,再用中级证书的公钥去验证服务器证书的数字签名。任何一个环节验证失败,就可以认为证书不合法。这就是整个证书链的认证过程:查看抓到的包的数据,发现只有两个证书。为服务端证书和中级 CA 证书。根 CA 证书呢?顺藤摸瓜找到它。首先看服务端证书。它内容如下:从这个证书中我们可以窥见这些信息:首先是 signedCertificate 字段的内容,即数字证书的数据:然后是证书颁发机构的签名信息:从上面的 issuer 可以了解到,认证该服务器证书的 CA 证书为GeoTrust SSL CA - G3,我们从 Certificates 找到对应的中级证书的内容如下(中级证书可以有好几级,我们这儿只有一级):可以得到中级证书名为GeoTrust SSL CA - G3,证书组织为GeoTrust Inc.。认证该 CA 证书的证书呢?还是看 issue 字段,认证证书名为GeoTrust Global CA,组织同样是GeoTrust Inc.。其实这个就是根 CA 证书。在这个请求中没有找到,但在浏览器或者操作系统可以找到。一般的浏览器和系统都会内置该 CA 证书。所以根证书是受浏览器或者操作系统信任的,无需其他证书做担保。如果想要自己的系统再信任某些非通用的权威机构的根 CA 证书,那么就去安装它。比如我的 Windows 系统就安装了GeoTrust Global CA证书:像我们平时使用 Charles 抓 HTTPS 就是这个原理,把 Charles 的 CA 证书安装在手机中,成为受信任的根 CA 证书。基本原理就是,Charles 代理作为 SSL 隧道,并没有透明传输,而是作为一个中间人,拦截了 SSL 握手信息,修改里面的 CA 证书。仿冒手机端和真实服务端建立连接获取主密钥,然后又仿冒服务端和手机客户端建立 SSL 连接,修改服务端证书的 CA 和数字签名,这样 Charles 就可以解析到加密的 HTTP 内容了。修改后的服务端证书如下,可以看到 issuer 被替换成了 Charles 的证书。
      Wireshark 抓包理解 HTTPS 请求流程

      本文由 在线网速测试 整理编辑,转载请注明出处。

          热门文章

          文章分类