HTTP / HTTPS 协议

发布于:2025-05-14 ⋅ 阅读:(14) ⋅ 点赞:(0)

目录

一、前言:

二、Fiddler 抓包工具:

三、http 协议:

1、http 请求:

1.(1)请求行:

1、(2)  请求头:

1、(3)  请求正文:

2、http 响应:

2、(1)  状态码:

2、(2)  响应头:

2、(3)  响应正文: 

四、请求行 GET 和 POST 方法的区别:

五、 https 协议:

1、https 工作过程:

1、(1)对称加密:

1、(2)非对称加密:

1、(3)中间人攻击:

1、(4)通过证书解决“中间人”攻击:


一、前言:

        http 和 https 协议是在应用层的协议,而 https 协议是在 http 协议基础上加了一个加密解密的工作。

        在此之前,要先了解 http 的协议格式,http 协议分为请求格式响应格式

二、Fiddler 抓包工具:

        当前网络环境中,纯使用 http 协议的网站很少,更多都是 https 协议的,那么,由于 https 是应用层的协议,一般是查看不了的,怎么才能查看?

        使用 fiddler 抓包工具,就能从当前计算机的网卡获取到经过的网络数据包,相当于一个 “门卫”,所有的网络数据包想要通过(发送和接收)数据包都要经过这个“门卫”。前面说到,当前网络环境中,纯使用 http 协议的网站很少,更多都是 https 协议,所以安装 fiddler 时要安装它的证书才能查看 https 具体内容。

        下面就是一次抓包的请求和响应结果:

        

         浏览器网址栏输入“bing”进入必应搜索引擎,fiddler 抓到了其中一条左边红色圈起来的信息,是当前一次发送的请求和响应。右边的上面绿色圈起来的是一次请求,右边下面蓝色圈起来的是当前请求的响应结果。

        点击 “Raw”,就能显示 http 的原始数据点击 “View in Notepad” 就能把当前的数据以行文本像形式显现。

三、http 协议:

通过上面的 fiddler 抓包,可以知道,http 协议分为四大部分:

1、http 请求:

        请求行,请求头(header),空行,请求正文(body)。

例如:        

不同颜色圈起来的四个部分,从上到下分别代表,请求行,请求头,空行,请求正文。

        其中,空行是请求头结束的标记。

1.(1)请求行:

请求行由三个部分组成,即:

        方法 + URL + 版本。

方法

表示客户端的请求类型:

        其中,GET和POST方法较为常见,但 GET 方法是最常用的 http 方法,常用于获取服务器的某个资源,比如在地址栏输入网址,或者在一些页面点击链接跳转的时候,大部分都是涉及 GET 方法。

        值得注意的是,GET 方法一般是没有请求正文的。(除非开发写代码的时候故意构造 body 也可以)。所以,GET 想要给服务器传递数据的时候,往往就是通过 URL 的 路径 / query string 来进行传递了。

        另外,POST方法在下面的场景会用到:

        比如在某个网站登陆的时候,输入的用户名和密码,其中的请求正文(body)就包含了用户输入的用户名和密码;或者上传图片资源 / 文件的时候,body 里上传的文件的二进制数据有时候会通过 base64 编码,变成文本内容,这是为了让服务器好处理。

         值得注意的是,POST方法是带有 body 的,通过 body 给服务器传递数据。

URL

        URL 就是我们平时在地址栏输入的内容(俗称网址),它表示唯一资源定位符,描述了网络上的某个资源的具体位置。互联网上的每个文件都有一个唯一的 URL 。在一些情况下,我们在地址栏输入的内容可能并不是完整的 URL。比如,当我们只输入一个域名 “ baidu.com ” 时,浏览器会自动补全协议部分,通常默认使用 “https://”,然后形成完整的 URL 进行访问。

        完整的 URL 包含的部分:        

 协议方案名:

        比如 http 和 https

登录信息(认证):

        由于现在的网站进行身份验证一般都不再通过 URL 进行了,一般都会省略。

服务器地址:

        此处是一个 “域名”,域名会通过 DNS 系统解析成一个具体的 IP 地址。 

服务器端口号:

        上面的 URL 中的端口号被省略了,当端口号省略的时候,浏览器会根据协议类型自动决定使用哪个端口,例如 http 协议默认使用 80 端口,https 协议默认使用 443 端口。

带层次的文件路径:

        指定服务器上资源的具体位置,以 / 分隔不同的目录和文件名。比如,你访问一个电商网站,最初进入的是首页,其 URL 可能是https://www.example.com/,这是网站的根目录级别。当你点击进入某个商品分类页面,如https://www.example.com/category/electronics/,这里的category/electronics/就比首页的路径多了一个层级,它表示electronicscategory文件夹下的一个子文件夹,用于存放电子产品分类相关的文件或页面信息。如果你再点击进入某个具体的商品详情页,如https://www.example.com/category/electronics/product123.html,路径又多了一个层级,product123.html表示具体的商品页面文件,它在electronics子文件夹下,通过这种层层嵌套的路径结构,网站能够准确地定位和展示不同的页面和资源,让用户可以按照一定的逻辑浏览网站内容。

查询字符串(query string):

        用于向服务器传递额外的参数信息,本质就是一个键值对的结构,通常以 ?开头,键值对之间用 & 分隔,键与值之间用 = 分割。

        比如,我在浏览器输入 “hello”:        

        得到的 URL :

https://cn.bing.com/search?q=hello&qs=n&form=QBRE&sp=-1&lq=0&pq=hello&sc=12-5&sk=&cvid=F469659E942240769939E00F71E6A946

        其中的 q = hello 就是用于向服务器传递其中的一个额外参数信息,参数名(q,qs,form......)一般由开发程序员自定义。

片段标识符:

        标识网页的某个部分,实现“页面内跳转”功能,一般文档类的网站会有这个。

值得注意的是:

        上述的 URL 这么多的部分,我们要重点关注 服务器地址 , 服务器端口,带层次的文件路径,查询字符串。

        并且,URL 中只能包含特定的字符集合,包括字母、数字、一些特殊符号(如 -_.~)以及保留字符(如 :/?# 等)。当 URL 中包含其他非 ASCII 字符或特殊字符(比如中文)时,就需要进行转义(一般使用utf - 8),以确保这些字符能在网络中正确传输和被服务器正确解析,避免出现歧义或错误。

        例如我在搜索引擎输入 “你好,世界”,在 UTF-8 编码下,“你” 的十六进制编码是 E4 BD A0,“好” 是 E5 A5 BD,“,” 是 EF BC 8C,“世” 是 E4 B8 96,“界” 是 E7 95 8C 。再发送 http 请求的时候,query string的会有一部分是 q = %E4%BD%A0%E5%A5%BD%EF%BC%8C%E4%B8%96%E7%95%8C 。

版本

     表示协议的版本。最广泛使用的版本是 HTTP /1.1  

1、(2)  请求头:

         每一行都是一个键值对,键与值之间用 “: ” 来分隔。由于 header 的 键(key)太多了,下面讲解一些比较重要的。

Host 描述了访问的服务器的 IP(域名) 和 端口号
Content-Length 描述了 body 的长度
Content-Type 描述了 body 的数据格式
User-Agent 标识客户端的类型和版本信息(如浏览器、操作系统),服务器可据此返回适配内容。
Referer 通过这个字段,服务器可以知道用户是从哪个页面链接过来的
Cookie 本质是浏览器在本地存储数据的一种机制

Host:

        与 URL 里的服务器地址端口作校验。因为针对 https 来说,https 是会把 header 部分加密的。

Content-Length 和 Content-Type:

        请求 / 响应 中存在 body 才会有这两个属性。

        Content-Length可以解决粘包问题,在 TCP 缓冲区中,会有多个 https 的请求,如果有 body ,则 header 必然会有 Content-Length,从 body 开始的位置开始读取Content-Length个字节就可以了

        Content-Type 其中一种常见的格式比如 JSON ,服务器可以根据 Content-Type 决定 body 如何使用。

Referer:

        不是所有的请求头都有这个字段(比如浏览器直接输入目的网址访问),例如,用户在百度上搜索某个关键词,然后点击搜索结果中的链接进入了我的网站,我的网站服务器就可以通过 Referer 字段获取到百度的搜索页面 URL,从而了解到用户是通过百度搜索进入的。

Cookie:

        由服务器生成并发送到浏览器保存,通常包含键值对形式的数据(如user_id=12345),当浏览器每次访问相同域名的网页时,会自动携带对应的Cookie发送给服务器。所以为什么在一些网站登录一次后,下次登录不用重新输入用户名和密码。

1、(3)  请求正文:

        请求正文(Body)的格式由请求头的 Content-Type 字段决定,下面是 JSON 格式的例子

{
    "key" : "value"
    ......
    ......
}

        

2、http 响应:

        状态行,响应头(header),空行,响应正文(body)。

例如:        

不同颜色圈起来的四个部分,从上到下分别代表,状态码,响应头,空行,响应正文。

        其中,空行是响应头结束的标记。

2、(1)  状态码:

        

以上红色圈起来的部分是要重要了解的状态码。

200:

     状态码 200 代表 “OK”,  表示服务器成功处理了客户端的请求。 

301:

        永久重定向,当服务器接收到客户端的请求,发现请求的资源已经永久性地迁移到了另一个地址时,服务器会返回 301 状态码,并在响应头的 Location字段中指定新的 URL。客户端收到这个响应后,会自动使用Location字段中的 URL 再次发起请求。简单理解就是服务器告诉客户端:“你要找的资源已永久搬家,以后请直接访问新地址!”(后续的请求都会被自动改成新的地址)。

302:

        临时重定向,表明请求的资源只是临时位于新的 URL,服务器收到请求后,指示客户端应临时重定向到另一个 URL,客户端会自动向新的 URL 发送请求。

403:

        表示访问被拒绝,有的页面通常需要用户有一定的权限才能访问(登陆后才能访问),如果用户没有登录直接访问,就容易见到 403。

404:

        表示服务器无法找到客户端请求的资源。这意味着客户端请求的 URL 在服务器上不存在。

500:

        表示服务器在处理请求时发生了内部错误。通常是由于服务器端的出现问题导致无法正常处理请求。

504:

        当服务器负载比较大的时候,服务器处理单条请求的时候消耗的时间就会很长,就可能会出现超时的情况。

2、(2)  响应头:

        与 http 的请求头结构类似。

2、(3)  响应正文: 

http 响应的 body 可能会包含 二进制数据,结构化数据(JSON ),文本类数据(HTML网页)。

        比如上面例子的黄色圈起来的就是二进制的数据,在数据量大的时候,为了提高数据传输效率,节省网络带宽和传输时间,服务器也经常会对二进制数据进行压缩后再传输。

        

四、请求行 GET 和 POST 方法的区别:

        GET 和 POST 方法其实没有本质区别,只是 http 的两个不同的方法,大部分情况下,使用 GET 的场景,也可以替换成 POST ,使用 POST 的场景,也可以使用 GET。只是在使用习惯上的区别而已。

        如果非要讲出他们两个的区别,那就是GET 通常没有 body ,要通过 query string 传递数据给服务器,POST 通常由body,不需要 query string 传递数据。

        网络上有个说法就是GET可以传输的最大数据量比 POST 小,这种说法是错误的,因为在 http 的官方文档中,并没有对 URL 的长度给出限制;网络上还有个说法就是GET传输的时候,query string 只能传输文本,不能传输二进制数据,这种说法也是错误的,因为 query string 可以通过 URL编码(urlencode)进行数据转换

五、 https 协议:

        前面说到,http 协议都是按照文本的方式明文传输的,这就会导致一个问题,那就是在传输的过程中会出现数据被篡改的情况。

比如:

我想下载一个 “天天动听音乐播放器” 。

再点击 “下载按钮 ”:

突然发现,他的这个下载名称链接,是 “QQ浏览器”的下载地址,这是怎么回事?

        由于我们通过网络传输的任何数据包都会经过网络设备(路由器,交换机等),那么运营商的网络设备就可以解析出你传输的数据内容,并进行篡改,这种情况也就是运营商劫持

        点击“下载按钮”,其实就是在给服务器发送了一个 http 请求,获取到的 http 响应其实就是包含了该 APP 的下载链接。被运营商劫持后,发现这个请求是要下载 “天天动听音乐播放器” ,那么就自动把交给用户的响应给篡改成 “ QQ浏览器”的下载地址了。

画图解释:

运营商为什么要劫持?主要是利益关系,这里不细说。

现在运营商劫持的情况大幅减少,https 协议的广泛使用就是一个重要原因!

1、https 工作过程:

1、(1)对称加密:

        生成一个密钥,明文到密文 和 密文到明文,都需要这个密钥来进行。对于 http 来说,对整个请求(首行,header,body)和响应(状态行,header,body)都进行加密。至于首行,虽然header的 Host 字段可以进行一定的校验,但攻击者仍然可能通过篡改首行的其他部分(如请求方法等)来进行恶意操作,无法保证整个请求的完整性和真实性。

        一个服务器要给多个客户端提供服务,那么他们通信之间使用的密钥,不能都一样。所以,既然每个客户端的密钥都不一样,那么,就得有一方生成一个 “随机密钥”,这一方可以是服务器,也可以是客户端。生成密钥的一方需要通知另一方密钥是什么,就也得在网络通信中把密钥传输过去。这也就会有个问题,如果网络传输中间有黑客入侵了某个设备,黑客把密钥获取到了,也不行,有没有什么办法?

        解决办法就是下面的非对称加密了。

1、(2)非对称加密:

        非对称加密有两个密钥对,一个专门用来加密的,另一个专门用来解密的,公钥是所有人都知道。而私钥只有一方是知道的。引入非对称加密,就是为了解决传输对称密钥的问题,通过公钥对密钥加密,通过私钥对密钥解密。

图解:

        公钥和私钥,是服务器生成的一个密钥对,私钥服务器自己持有,而公钥是公开的,所有人都可以知道。

        上述图的流程,公钥把对称密钥加密后,传输给服务器,服务器通过私钥解密,得到密钥具体内容是 “888888”。这样,由于客户端和服务器双方都知道密钥的具体内容,之后的通信就可以使用密钥加密数据传输了。

        由于上面的对称密钥传输的过程,黑客只能拿到公开的公钥,公钥只能用来解密,就无法知道加密后的具体对称密钥是什么了。

        到这里,安全性还并不完美,还会有“中间人”攻击。

1、(3)中间人攻击:

        首先,客户端向服务器询问公钥,服务器返回的公钥经过黑客入侵的设备,黑客自己生成一对公钥和私钥,黑客再把自己生成的 公钥 pub2 返回给客户端。

        之后,客户端拿着 pub2 公钥对密钥进行加密,经过黑客入侵的设备,由于密钥是通过 pub2 来加密的,所以黑客拿着自己生成的私钥来对密钥进行解密,得到了对称密钥的具体内容,再通过pub1 加密密钥返回给服务器。服务器再通过自己的私钥解密获取到对称密钥具体内容。

        上述可以看到,由于黑客在此过程中,得到了对称密钥,还是会有安全问题,怎么办?下面,引入证书就能解决“中间人”攻击的问题。

1、(4)通过证书解决“中间人”攻击:

        引入证书,就是为了解决“中间人”攻击的问题,证书解决的核心问题,就是让客户端识别当前返回的公钥是服务器本身的,还是黑客伪造的。服务器一方的运营者会向公正机构获取证书,证书会包含的字段有:证书的发布机构,证书的有效期,证书的所有者,服务器的 ip/域名,服务器使用的公钥和私钥,数字签名。(数字签名可以理解公正机构对上面包含的内容计算的一个校验和,再使用自己的私钥加密)。

        网络通信的时候,客户端询问服务器返回的就是证书,返回的证书,客户端会对证书的字段通过同样计算校验和的算法,计算得到一个校验和 check1 (客户端自己计算的),再使用公正机构的公钥来对证书的数字签名字段解密。得到 check2 (公证机构计算的)。

        如果 check1 == check2 ,说明证书没有被篡改过,证书的公钥就是科学的(服务器的公钥)。

        如果 check1 != check2,说明证书被篡改了(有可能篡改了证书里服务器的公钥),此时浏览器 / 客户端会弹出警告,显示说网站存在风险 / 证书不受信任。

        

注意:

        1.上述的流程中,黑客如果篡改公钥,那么客户端计算的 check1 与 证书带有的 check2 会对不上,客户端 / 浏览器就会识别出来。

        2.上述流程中,黑客能否自己搞一个证书,替换服务器的返回的整个证书?

        答案是不能,证书包含了服务器的 ip / 域名,假如客户端想要访问百度,返回的证书却是其他的 ip / 域名,浏览器 / 客户端很容易识别出来。

        3.黑客是否篡改公钥的同时,也把数字签名改了?

        答案是不能,因为数字签名是通过公正机构的私钥来加密的,这个私钥只能用来加密,而黑客很难获取对应的公钥解密。因为公正机构公钥不是通过网络获取的,是内置在操作系统中的。 


网站公告

今日签到

点亮在社区的每一天
去签到