TCP/IP、HTTP的关系,HTTP和HTTPS区别,抓取HT
为啥要写这篇文章呢,是因为之前也搜过关于TCP/IP、HTTP的相关知识点,但是因为知识点太零散,所以理解的不透彻,过一阵就忘没了,只记住了TCP需要三次握手、TCP是有状态的,UDP是无状态的等等。。。 然后最近抽时间将《图解HTTP》读了一遍,收获非常大,就计划结合之前学习的零散知识点融合一下写一篇文章,就算是巩固吧,下面开始正文
咱们现在使用的网络传输数据(上网、聊天),都是要遵循"TCP/IP协议族"的,这是可以通信的基础,而HTTP协议是TCP/IP协议族里的一部分。
为啥遵循TCP/IP协议是可以通信的基础呢?因为无规矩不成方圆。比如我要给你寄一封信,为啥我给你寄的信你可以收到,是因为我寄信时遵循了好多规定,比如我必须要把我写的信放到信封里,我放到一个纸盒子里,人家就不给我寄,比如我必须要贴邮票,不贴人家也不给我寄,这就是协议。用信封,贴邮票,就是寄信需要遵循的协议,不遵循,信就发不出去,同样,TCP/IP协议族(是一个统称)就是为网络传输定制的,你不遵循这些协议,就上不了网,发不了消息,那TCP/IP协议具体需要遵循啥呢,下面咱们就来说说
首先又到了之前听到吐听到恶心的OSI模型
OSI(Open System Interconnect),即开放式系统互联。 一般都叫OSI参考模型,OSI定义了网络互连的七层框架(物理层、数据链路层、网络层、传输层、会话层、表示层、应用层),好了,去他娘的7层,谁他妈记得住。。。。
SO...咱们先说简单的,虽然OSI参考模型是7层,但是TCP/IP参考模型就4层,也就是说支持网络传输的TCP/IP协议族可以分为四大块,一下子少了好多,就可以容易理解一点了,然后咱们就从4层说起,这4层就是 应用层->传输层->网络层->链路层。
比如我给身在美国的你寄一堆好吃的,我得把吃的包装一下,贴上快递单,写上收信人的地址,国家、城市、小区、几号楼,然后送到顺丰快递点,顺丰快递点得先看目的地在哪,然后规划出飞机航线,然后就运送到飞机场,装飞机出发了。对应的关系如下
应用层--负责包装数据--将信放到信封、贴邮票、写地址
传输层--负责运输数据--运送邮件的飞机
网络层--负责导航规划路线--邮局里规划路线的人(可能拿着高德地图)
链路层--负责将信件弄成可上飞机的标准--邮件在坐上飞机在空中飞之前,需要经过安检贴标签等,弄成符合可以空运的样子,下飞机标签再撕掉
那么每一层对应到TCP/IP协议族(协议族里有很多协议)里又分别对应到哪些呢,请看下面,红色标注的是考试的重点,哈哈
应用层(负责包装数据)—-HTPP协议终于要露脸了,他就是处于该协议。他的作用就是生成针对目标服务器的请求报文。那报文包含啥呀,请求报文是由请求方法、请求URL、协议版本、可选的请求首部字段、内容实体构成。比如我web端或客户端要将一个“name”字段传到服务器,那么报文就是对name的包装,比如我是用get还是post请求方法,请求的URL是啥,内容实体"name",content-type等,虽然有些是你在代码里设置的,但是需要将你设置的内容按照http协议里要求的格式进行封装,然后服务器也会按照这个协议定义的格式进行解析,拿到"name"这个字段。所以可以简单的理解为对数据按一定格式包装,当然FTP协议也属于这一层,区别可自行搜索。在这一层的还有DNS(域名解析)服务,将URL解析成对应的IP地址,比如www.baidu.com会解析成192.166.xx.xx,用户通常使用域名来访问服务器,而不是IP地址,因为与一串数字的IP地址相比,用字母配合数字的表现形式来制定计算机名更符合人类的记忆习惯,查找过程如图
传输层(负责运输数据)---应用层把要传输的数据包装好了以后,就会给到下一层,也就是传输层,传输层负责两台设备之间的数据运输,TCP和UDP都属于这层,这个大家应该就很熟悉了吧,TCP就是提供可靠的字节流服务。字节流服务,就是可以将大的数据分割成小的数据进行管理传输,可靠是指可以把数据准确可靠的传给对方。大的数据分成小块的数据就不说了,很简单,为了提供可靠的传输,TCP在正式传输数据前采用了三次捂手的策略,一保证传输的可靠性,三次捂手这个也是听了无数遍了,如图所示:
这里再啰嗦几句,为啥要进行三次握手呢,看上图。如果正常情况下,第一次握手,发送端给接收端发了一包数据,说明发送端已经准备就绪,第二次握手接收端给发送端回了一包数据,说明接收端是准备就绪的,现在发送端和接受端都准备就绪了,完全就可以确认双方都在线,并且可以传输数据了呀,为啥还要进行三次。因为三次握手是更严谨的,考虑了异常情况的,比如,第一次握手,发送端给接收端发送了一包数据,结果恰巧网络不好,等了好几秒数据还没到接收端,此时发送端放弃了,不准备继续通讯了,自己去玩了,等了一分钟,接受端收到了,然后就回了一包数据,此时第二次捂手结束,如果这时就默认连接成功的话,其实发送端已经不在了,白白浪费了一个接受端的资源,所以三次握手更严谨(当然我觉得这只是尽可能的避免,还是无法百分之百避免,万一恰巧第三次握手网络不好了呢 ~ ~哈哈)
网络层(负责导航规划路线)--传输层进行握手和传输数据的时候,如何找到对方的就得靠网络层了, IP协议就属于该层,IP协议的作用就是规划数据可以走哪条路到达服务器,并把数据给服务器,规划的前提是知道服务器的IP地址和服务器的MAC地址,IP地址是指上网设备在网络世界中被分配到的地址,MAC地址是指上网设备(手机、电脑)中网卡的编号,IP地址已经在应用层通过DNS服务解析出来了,现在就差服务器的MAC地址,有了服务器的IP地址和MAC地址以后,就可以查找到服务器了。采用APR(Address Resolution Protocol)地址解析协议,就可以根据IP地址反查出电脑的MAC地址(服务器网卡的地址) 。但是互联网世界这么大,网线中间经过了无数个路由器进行连接中转(并不是咱们家里自己用的WIFI发射信号的路由器),所以每个路由器都只知道一部分电脑IP地址对应的MAC地址,所以根据APR协议查找MAC地址时可能需要中转好几次,如图
中转几次就找到去往服务器的路了 ~
链路层(中介)--这一层就是硬件层面的东西了,说白了就是让计算机这块塑料金属组装的玩意和网络世界连接起来的硬件部分,比如网卡等。可以将网线传输过来的电信号,转成010101的数字信号,然后就可以变成我们想要的数据。
然后用一张图总结性的表示一下
然后再零散的说一点别的
1. 长链接和短链接。
(1) 咱们都知道聊天软件用的都是Socket长连接,为啥用长连接,就是因为会话频繁,我一句你一句,可能连续聊好几个小时,如果用短连接,发一句话就断开,就会出现连接->断开->连接->断开 ~ ~那得浪费多少资源。HTTP协议的初始版本中,每进行一次HTTP通信都要断开一次TCP连接,断开就意味着如果再次连接就要再次进行三次握手,就要消耗资源,比如访问一个网页,里面包含很多图片资源,就会请求很多次,同时也会重复多次断开、三次握手、断开、三次握手。。。 为了解决上述问题,HTTP/1.1和部分HTTP/1.0添加了持久连接功能(keep-alive),持久连接的特点是,只要任意一点没有明确提出断开连接,则保持TCP连接状态,也就是一次握手可以通信多次,那既然HTTP都支持长连接了,为啥聊天软件用的还是scoket不用http呢,因为scoket建立长连接后可以是双向通信的,客户端可以给服务端发,服务端也可以给客户端发,而HTTP只能是单向的,所以还得用socket(scoket是啥呢,刚开始的时候说了,HTTP属于应该用层,TCP属于传输层,咱们平时用的HTTP请求是直接操作的HTTP,然后HTTP去帮助咱们调用TCP,咱们没有直接去调用TCP,Scoket可以看做是对tcp的封装,便于咱们直接调用) ~ ~是Scoket,拼写错误
2 Cookie
HTTP协议是一种不保存状态的协议,自身不对请求和响应之间的通讯状态进行保存,也就是说HTTP这个级别,对于发送过的请求或响应都不做持久化处理,每次请求响应都是全新的都是独立的,当初就是这么设计的(不需要记录状态,服务端减小CPU、内存资源消耗),但是随着Web的不断发展,这种无状态连接的弊端就展现出来了,比如用户登录到一家购物网站,即使用户调到该站的其他页面,也需要一直保持登录状态,这个时候网站就得需要记录用户的状态,判断是谁发过来的请求,这是怎么做到的呢,明明只是在刚开始上传了用户名密码。为了实现保持状态的功能,HTTP/1.1引入的Cookie技术,Cookie技术是通过在请求和响应报文中写入Cookie信息来控制客户端的状态,Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去,服务端发现客户端发送过来的Cookie以后,会去查这是哪个客户端发送过来的,然后得到之前的状态信息(也就是类似在商场门口看自行车收费的,我给你一个小木头牌子,给车上挂一个木头牌子,写着标号,你手里的和车上的标号相同,你等你回来把木头牌子给我,根据标号我就知道哪辆自行车是你的)
3 HTTP在传输数据时可以在传输过程中通过编码提升传输速率
比如我们向待发送邮件内增加附件时,为了使邮件容量变小,我们会先用ZIP压缩文件之后再添加附件发送。HTTP协议中有一种被称为内容编码的功能也能进行类似的操作。内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。但是编码是有计算机来完成,因此会消耗更多CPU等资源。常见的内容编码 1.gzip(GNU zip) 2.compress(unix系统的标准压缩) 3.deflate(zlib)
4. HTTP和HTTPS的区别
(1)HTTP通信使用明文(不加密)内容可能被窃取。由于HTTP本身不具备加密功能,所以无法做到对通信的整体进行加密,也就是无法对整个报文进行加密(请求报文是由请求方法、请求URL、协议版本、可选的请求首部字段、内容实体构成)只能对咱们自己能控制的请求的内容实体进行加密
(2)HTTP不验证对方身份,数据可能会遭到窃取,HTTP本身不就被校验对方的能力,你只要有请求我就响应,你只要有响应,我就接收,比如我请求了一张正常的图片,如果这个请求呗拦截,然后伪造的服务器或给我返回一张“黄图” ~ ~ 比如哪天访问github,界面全是“黄图”
在网络世界中窃取一点数据时非常容易的,比如抓个包啥的,就会导致HTTP请求开始不安全了
上面说了两点,第一点,咱们开发人员还是可以通过别的方法进行优化的,虽然HTTP不能对整个通讯加密,但是我可以对我需要传输的参数加密,比如请求参数有个{name:xiaoming},可以对"xiaoming"进行AES或者别的加密方式加密后再传输,虽然不如将整个通讯的内容都加密安全,但是至少可以增加破解的难度,但是第二点,确认响应的服务器就是自己的服务器,开发人员是做不到的,无法确认是自己的服务器,就会造成请求返回的数据,可能是一个假的服务器返回的假数据。
因为HTTP有这些不足,所以就在HTTP的基础上加入了SSL(Secure Socket Layer)安全套接层来对整个通信进行加密,HTTPS就诞生了,HTTPS就是身批SSH协议外壳的HTTP,所以HTTPS和HTTP的区别实际就是,HTTPS请求,是将整个通信都加密了,也就是对整个报文进行加密了(请求报文是由请求方法、请求URL、协议版本、可选的请求首部字段、内容实体构成),SSL不仅提供加密处理,而且还使用了一种被称为证书的手段用于确定对方。证书是由值得信赖的第三方机构颁发的,并且伪造是异常困难的。(BUT也出现过机构泄露证书的时间,所以加密没有百分百安全的)。HTTPS请求会在通信前进行证书认证身份
然后咱们说说HTTPS是怎么规避以上两点缺陷的
(1)首先说一下,是如何将整个通讯的数据都加密的
说之前咱们先了解一下加密方式有几种,目前的加密方式分为对称加密、非对称加密、不可逆加密
对称加密:只有一把秘钥,就是加密和解密用的是同一个秘钥,优点是加密时计算量小,加密速度快,缺点就是密钥容易泄露,传递的过程中被坏人看到、或者是人为的泄露,比如AES就是对称加密
非对称机密,有两把秘钥,就是指加密的密钥和解密的密钥不是同一个,优点是这样就可以放心的把加密的密钥公开,解密的密钥自己留着,缺点是加密时计算量大,速度慢,比如RSA
不可逆加密(hash)就是加密以后是解不了的,但是每次加密的结果是一样的比如MD5加密。
假如咱们HTTPS用对称加密的方式进行加密,在客户端请求服务器时,客户端会生成一把对称加密的秘钥,然后给服务器,说我之后发给你的数据都是用这个秘钥加密的,你要用这个秘钥解密,你回应给我的数据也要用这个秘钥加密,加密方式是好的,因为对称加密速度快,但是有一个弊端那就是下图
你的秘钥在给服务器的过程中,很容易被人窃取,坏人知道秘钥以后,你之后传输的用这把秘钥加密的数据,坏人都是可以解密看到的,所以这种加密时行不通的
上述方法行不通那就尝试一下非对称加密的方式进行加密,非对称加密就是服务端生成一个公钥一个私钥,将公钥给客户端,客户端发送的数据用服务端给的公钥加密,服务器接收到数据用自己的私钥解密,反过来一样,客户端也生成一对秘钥,公钥给服务端,私钥自己留着
如图所示,公钥虽然可以被坏人看到,但是是无所谓的,之后双方传输的数据都是用对方的公钥加密,想看到数据得用私钥解密,但是私钥都在各自手里,所以看不到,数据安全是没问题的,但是又带来另一个问题,就是非对称加密,加密解密都比较慢,影响传输效率,所以最终HTTPS选了,对称加密和非对称加密结合的方式,如下图
HTTPS采用的是对称加密和非对称加密都用的混合加密,为了传输效率高,在传输数据时用的是对称加密,但是客户端为了把对称加密的key安全的传给服务器,结合了非对称加密,服务端生成一个公钥,一个私钥,给客户端一个公钥,自己留着一个私钥,然后客户端拿着服务器的公钥将自己产生的 "对称加密的key" 用公钥加密,然后传给服务器,服务器用自己的私钥解密,安全的拿到key。虽然在传输过程中可以被坏人看到,但是传输的是用公钥加密的key,但是因为不知道私钥,解密不了,拿不到对称加密的秘钥,所以也只能眼睁睁的看着他在眼前经过 ~
(2)第二点HTTPS比HTTP高明的地方还有就是可以识别是不是自己的服务器,是怎么做到的呢(结合下面的图看)
上面已经说了,为了安全的传输对称加密的秘钥,服务端会生成公钥(1)和私钥(1),私钥(1)自己留着,公钥(1)给客户端,但是客户端怎么知道这个公钥(1)就是咱们自己服务器不是冒充的,那得用到权威的证书颁发机构(CA),这个机构必须是百分之百的安全,人们必须完全信任他,在这个前提下,服务端在给客户端公钥(1)之前,服务端先拿着公钥(1)去证书颁发机构申请证书签名(如下图第1步),证书颁发机构会用服务端给的公钥(1),并且再加上一点别的信息,比如这个服务器的域名等信息,加上别的信息之后进行hash运算(不可逆加密),运算后的信息叫“信息摘要”,证书颁发机构用自己的私钥(2)对摘要进行加密,加密后的数据叫“数字签名”,然后给到服务器申请人员(如下图第2步),然后服务端给客户端公钥(1)的时候,将证书颁发机构生成的“数字签名”和“公钥(1)”一起给到客户端(如下图第3步),
证书颁发机构让手机厂家提前将自己的公钥(2)预置到手机里(在下图中服务器的公钥私钥编号为(1),认证机构的公钥私钥编号为(2)),当服务端将 “公钥(1)+数字签名” 一起给到客户端时,证书颁发机构预置到手机里的公钥(2),会将数字签名解密,如果能解密,说明这是一个合法的、经过认证机构加密的数据,如果是伪造的,是解密不了的。然后将 "解密出来的数据(也就是上面说的信息摘要)" 和 "服务端传过来公钥(1)再次加上上面所说的别的信息比如本次请求的域名,进行hash" 对比,是否一样。如果是,则说明这个服务器就是自己的服务器。(如果一个伪造者将自己的服务器在认证机构申请的"数字签名+伪造者的公钥"给客户端,虽然客户端能解密,但是"解密出来的hash值" 和 "用本次请求域名+传过来的公钥(1)hash出来的值"是不一样的,因为域名肯定不一样,所以不会认证通过,请求会终止)
5 抓包工具是怎么抓取数据的
首先了解一下“代理”,代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。
抓包工具,咱们都知道,抓包工具,抓包前的首要配置就是要将手机的代理打开,代理的地址就是电脑的IP,这样就可以让抓包工具充当代理的角色。
非HTTPS的抓包,咱们就不用说了,因为传输的时候都是未经过加密传输的,所以,抓包工具作为代理,所有请求和响应的数据都经过他,都是可以看到的,但是HTTPS请求传输的数据都是经过对称加密方式加密的,然后又不知道秘钥,只能抓取到一堆乱码。咱们都知道要想用抓包工具抓取HTTPS的请求,咱们都得下载一个证书,并且需要在手机里信任此证书,那么抓包工具是为啥需要信任这个证书才能抓取到HTTPS传输的原始数据呢,要想看到原始数据首先要获得对称加密的秘钥,因为最终传输数据时,用的是对称加密的秘钥,但是对称加密的秘钥传输过程中是用服务端的公钥(1)加密过的,抓包工具没有服务端的秘钥(1),所以拦截到也解密不出来,那该怎么办呢,如下图(黑色X表示线路被截断,蓝色的步骤是比正常请求多的)
在下图第3步,服务器给客户端 "数字签名+公钥(1)" 的时候,被抓包工具拦截(如图第4步),然后给了客户端一个自己的公钥(3),以及自己对公钥(3)进行签名加密的数字征证书(如图第5步),理论上来说,客户端是会认为抓包工具给的这些东西是不合法的,因为这不是认证机构给的数字证书,内置在手机里的认证机构的公钥(2)解析不了,但是手机却当成合法的了,为啥呢,关键的一步就是在这,上面咱们说了,要想 抓取HTTPS的请求,要下载一个抓包工具给的证书,并且在手机里信任该根证书,就是因为信任了这个证书,所以当抓包工具将自己伪造的公钥以及数字证书给到客户端时,你刚才下载并且信任的那个抓包工具的根证书站出来说,这个是合法的,所以抓包工具的公钥和证书就被认为是合法的放行了,验证通过以后,继续后面正常的流程,就是用给的"公钥(3)"(客户端以为是服务端的公钥,实际上是被抓包工具掉包了,是抓包工具的)将对称加密的秘钥进行加密,并且传给到服务端(如图红色的第4步),给到服务器的过程中又被抓包工具拦截到如图第6步,因为是用自己的公钥(3)加密的,自己有私钥(3),所以就可以解密,解密后拿到了对称加密的秘钥,走到这就基本大功告成了,但是还有最后一步,就是这个经过加密的秘钥不能直接转发给服务器,因为服务器是解密不了的,因为不是服务器的公钥(1)加密的,如果解密不了,这个请求就会终止,所以接下来就是用第4步拦截下来的公钥(1),将自己解密出来的秘钥进行加密,并且转发给服务器(图第7步),这样的话服务端就可以用自己的秘钥(1)进行解密,获取到对称加密的秘钥,然后就开始进行数据传输了。