HTTP协议HTTP协议初体验,深入浅出网络协议
Posted 意愿三七
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTTP协议HTTP协议初体验,深入浅出网络协议相关的知识,希望对你有一定的参考价值。
前言
本文全文2w字左右阅读完成需要二十分钟左右,文章介绍了HTTP和HTTPS,以及抓包软件fiddler的基本使用工程,了解基本网络协议对以后编程有莫大好处,本文不像高校《计算机网络》教程上所头头是道,文章以丰富的例子,问答形式,代码实验来解决问题,对于入门的朋友可以值得一看,欢迎大家积极提出问题,会一一改正的。
一、HTTP是什么?
HTTP (全称为 “超文本传输协议”) 是一种应用非常广泛的 应用层协议.
HTTP协议,也可以说是前后端交互的桥梁
我们要先搞明白为什么当前我们的网站 / 浏览器,一点击就可以访问一个页面,
其实这都是HTTP协议的功劳,我们可以看看下面的图:
可以看见用户的浏览器(客户端)发出一个请求 ,服务器就给出相对的响应
名词介绍:
客户端:主动发起网络请求的一端
服务器:被动接受网络请求的一端
请求:客户端给服务器发的数据.
响应:服务器给客户端返回的数据
这些操作都是基于 “网络” 来进行的.
协议:让传递消息的双方,能够对上号,就像暗号那样~
HTTP重要的特点: 一发一收的模式
网络编程中,除了一发一收之外,还有其他的模式,场景
多发一收:上传大文件
一发多收:看直播
多发多收:串流~~
二、Fiddler软件抓包
我们如果想看见浏览器和服务器之间的交互数据,可以使用浏览器自带的开发工具,但是那样数据并不详细
1.下载安装Fiddler
2.关于Fiddler的使用
左侧窗口,显示了当前所有的请求是啥
会记录下机器上每个程序和服务器之间的http请求~ 不仅仅记录浏览器的, 因为后台还有许多程序
也会访问服务器。
如何清空Fiddler的窗口:
1.选中一条,如何按ctrl+a ,然后按delete
我们如何去使用这个工具呢?
我们可以试试 百度搜索页
然后我们想看到得发出的HTTP请求 可以先上面的那样~
也可以变成文本 直观的看:
看HTTP响应也是一样:
右下角完整的HTTP响应
那么为什么Fiddler可以获取这个请求呢?
Fiddler之所能够获取这些HTTP请求的详细情况,主要是因为此处的Fiddler相当于一个 “代理”程序如下图:
三、HTTP协议格式
1.HTTP的请求格式
-
首行
可以看见这里是HTTPS
那么HTTP和HTTPS有什么区别呢?
HTTPS是HTTP的加强版~,当前网站上的很多网站,都是HTTPS
HTTPS和HTTP相比非常相似,只是多了个 “加密层”
注意如果我们第一次使用发现没有HTTTPS 的可以像下面图片一样设置一下:
要勾选上,并且按照提示安装证书。
大家来看看首行:
GET https://www.baidu.com/ HTTP/1.1
- 协议头(header)
里面都是键值对 结构,每一个键值对,占一行,键和值之间使用:空格来分割
- 空行
空行是协议头的结束标记
- 协议正文(Body)
空行后面的部分,有的请求有,有的没有
2.HTTP的响应格式
响应的格式在这里看:
-
首行
-
协议头(header)
-
空行
协议头结束的标记
-
响应正文
响应的正文,往往就是被显示在浏览器上的,最常见的响应正文格式,就是html
但是大家看上面是不是看不出来是HTML ,因为这里是压缩了,我们解压缩一下就可以了
然后打开就看的清楚了
为什么要压缩呢?压缩之后,网络传输的数据量就变少了,然后更节省网络
3.HTTP格式总结
使用以下的图来看:
四、HTTP 请求 (Request)
1、认识 URL
- URL 基本格式
平时我们俗称的 “网址” 其实就是说的 URL (Uniform Resource Locator 统一资源定位符).
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它.
URL 的详细规则由 因特网标准RFC1738 进行了约定.点击查看
最完整的URL如下:
URL不仅仅是使用在HTTP/HTTPS里面,很多协议也可以使用URL
比如JDBC 编程也使用URL,只是协议方案名不一样。
登录信息
现在我们很少看见这样的格式了
服务器地址
地址可以是一个IP地址,也可以是域名
ip地址:就是描述网络上的一个具体位置
因为ip地址有点长,不容易记,所以我们大部分时候使用域名
端口
分别是哪一个应用程序
ip地址可以定位到是哪一个主机,一个主机上有许多应用程序同时在跑,具体把请求交给谁,使用端口号来区分
每个程序在访问网络的时候,都会关联上一个或者多个端口号~
通过端口号就能区分出当前的请求给谁
平时在上网的时候,地址栏里一般看不到端口号,不是说没有,而是有时候如果端口号不是特殊的,那么浏览器会加上默认端口:
对于HTTPS的请求,浏览器会自动加上443端口 ,因为一般的HTTPS服务器都是用443
对于HTTP的请求,浏览器会自动加上80的端口
一般的HTTP服务器都是用80的端口
当然我们也可以手动的加上其他的端口(如果服务器使用的别的端口的话)
PATH 路径
dir / index.html
访问该服务器程序上的哪个资源. 比如是要访问哪个html,访问哪个图片
查询字符串 QueryString
一般网址的查询词具体关键的有。
其实这个后面许多也是键值对,
大就可以看见搜狗以&作为键值对之间的分割符,
以 =作为键和值之间的分隔符。
这些键值对都是搜狗自己程序员定义的,百度也有自己的。
片段标识符
能让我们跳转到哪一部分,html里面有 A标签的 #
上面许多内容会省略,大家要认识出来,常见情况:
如果省略域名:继续访问当前网站的其他资源
如果省略端口号:浏览器自动填充默认端口(80 / 443)
如果是省略带层次的路径: 表示访问 /目录
如果省略query String: 这个本来就是可选的,客户端可以给浏览器传递参数,也可以不传递
如果省略片段标识符:这个经常没有
URL中的url encode
在浏览器看见的地址我们复制下来回你发现他不一样了
复制下来:
是不是中文变成其他的了,为什么呢?
因为queryString 里面如果包含了特殊的符号或者中文符号,就需要进行urlencode。
例如: / # ? & 等等
万一querystring 里面也存在特殊符号,就可能导致URL格式错误 ,因此就需要对这些符号进行转义。
对特殊符号的转义叫做urlencode,反过来解析叫做urldecode。
这里的转义就是直接取当前的字符/字符串 的内存的16进制 把每个字节前加上一个%
我们看看c++ 的转义:
C%2B%2B 其实 这里的+ 就是 %2B 在内存的16进制中
大家还有要注意这个的 有的浏览器会自动进行encode,有的不会~
关于解析 我们可以去网上找一下urlencode解析
2、认识 “方法” (method)
2.1 什么是方法
HTTP的方法就是请求报文中的首行的第一个部分~~
设计这个HTTP方法协议是希望不同的方法有不同的“语义”
比如GET是获得从服务器获取资源。
POST传输文件实体,作者是希望大家这样使用,但是我们现在程序员使用这些方法是‘’非常随心所欲‘’的,并不会按照规定的那样。
下面我们来介绍两个常用方法: GET \\ POST
2.1.1 介绍(GET)
在此之前,介绍一下HTTP的协议版本 1.0,1.1,以及 2 , 3,但是2和3 版本还没有普及,以下介绍的是1.1版本的
- 在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
比如打开搜狗的主页:
2.HTML 中的 link, img, script 等标签, 也会触发 GET 请求.
img的scr属性,写了一个url,浏览器会自动根据img的src构造出一个HTTP的请求
3.还可以使用JS,直接在浏览器前端构造HTTP GET 请求(ajax)
4.各种编程语言(只要能够访问网络)就可以构造HTTP请求
GET 请求特点
-
首行里面的第一个部分是GET
-
URL里面query string 可以为空,也可以不为空
不为空:
3.GET 请求里面有很多组header键值对~ -
GET 请求一般body是空的 (GET请求也可以有body,但是很少见)
注意网上是GET 请求有长度限制,这个上限主要是因为URL的长度存在上限,还有的把长度标出来了,其实这些都是错误的,
RFC这个文档里面约定了很多和网络协议相关的标准
2.1.2 介绍(Post)
POST请求特点
最常见的场景就是 登录
输入 用户名和密码之后就会产生一个post请求
特点:
1.首行的第一个部分就是post
2.URL后面没有query string (一般都没有个别情况会有)
3.header这里也是有若干的键值对结构
4.body一般不为空这里的具体数据格式,由请求header中的Content-Type来描述 (Body的具体长度,由请求header中的Content来描述)
图片第四行有 。
其实互联网的信息,并不是很安全,我们访问的各种数据都是在网络上要经过各种的硬件设备进行传输,在这些设备上进行“抓包”可以看见具体内容。
我们解决的方案就是“加密”,不用明文传输密码,而是在客户端这边对密码进行加密,以密文进行传输。
类似于:你上课叫妹纸中午去干饭,你写纸条给她,但是有点距离,你又不好意思让其他的同学知道你们之间的小秘密,以特殊的字符代替关键字
2.1.3Get和Post的区别
回答这个问题首先要盖棺定论:没有本质上的区别,使用Get的场景也可以使用Post
但是在具体使用上,还是存在一些细节上的区别的:
- (最经典)Get习惯上,吧客户端的数据通过query String 来传输,(body部分是空),post习惯上把客户端的数据通过body来传输,(query string)是空的 (习惯上不是必须更不是百分之百)
- 语义上的区别:Get习惯上用于从服务器获取数据,post习惯上客户端给服务器提交数据
- Get方法程序员一般情况下,程序员会实现成为“幂等”,post请求不要求实现幂等(请求如果重复被发送了,不会产生负面效果)
正面影响:(比如你要去抢一个物品,打开页面的时候发送一个请求,这里打开的是否是开始买的状态,刷新一次发送一个请求,但是这个请求不会影响,因为只是是否可以购买 没有其他操作)
负面影响:现在我进行下单,服务器正卡着,我不知道是否成功,退出又重新下单,重复3次,问题来了这几个请求会不会产生负面效果,到底是一个单,还是3个单呢?
所以我们Get一般实现幂等,重复不会出现影响,下单post一般不实现幂等,可能会出现问题。(也是“标准文档”的建议,也不是程序员必须要遵守的)
- Get请求可以缓存,可以被浏览器保存到收藏夹中,但是post不行
对于这个问题,网上有些说法,也是不准确的
1. Post比Get更安全
问:因为Get实现登录,习惯上是把参数放到queryString 此时浏览器的url显示了用户的用户名和密码,这样就感觉不安全,post实现登录,把参数放在body里,此时不显示在浏览器里,不就更加安全吗?
答:其实安全和不安全取决于是否加密,以及加密算法的强度,和你的东西在url还是body里,没有啥关系,毕竟一抓包都一目了然。
2.传输的数据量比Get的更多~~,原因Get的URL上有上限
答:其实RFC标准中明确说了,不对URL长度做限制
3.Get只能传输文本数据,POST可以传输文本和二进制数据
答:Get完全可以传输二进制数据,只要对二进制数据进行urlencode就可以放到url里面了,Get大不了也可以直接把数据放到body
3、其他方法
- PUT 与 POST 相似,只是具有幂等特性,一般用于更新
- DELETE 删除服务器指定资源
- OPTIONS 返回服务器所支持的请求方法
- HEAD 类似于GET,只不过响应体不返回,只返回响应头
- TRACE 回显服务器端收到的请求,测试的时候会用到这个
- CONNECT 预留,暂无使用
了解即可,能说出来就可以了
4、认识请求 “报头” (header)
1、Host
表示请求所对应的服务器的地址,地址里面可以是域名,也可以是IP,也可以是手动指定的端口号,有人就会问,那host信息,在url里面是不是也存在,其实网络上存在一种特殊的程序:“代理”,代理就像海淘,可以自己出国,也可以找朋友给你买,这样就叫代理,不方便的时候,可以通过这样的情况来代理购买。
2 、Content-Length、 Content-Type
Content-Length表示body的长度,单位是字节
Content-Type表示body的格式
如果这个请求是有body的(post),此时就会同时带上这两个header
如果这个请求没有body(Get),此时就不会带有这两个参数
2.1、 Content-Type 常见取值
- application/x-www-form-urlencoded: form 表单提交的数据格式. 此时 body 的格式形如 queryString的格式来组织
title=test&content=hello
- multipart/form-data: form 表单提交的数据格式(在 form 标签中加上
enctyped=“multipart/form-data” . 通常用于提交图片/文件. body 格式形如:
Content-Type:multipart/form-data; boundary=----
WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name=“text”
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name=“file”; filename=“chrome.png”
Content-Type: image/png
PNG … content of chrome.png …
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
- application/json: 数据为 json 格式. body 格式如下,我们抓包会经常遇见这样的
“username”:“123456789”,“password”:“xxxx”,“code”:“jw7l”,“uuid”:“d110a05ccde64b16
a861fa2bddfdcd15”
js里的对象也是这样的格式 json格式就是源自于js的对象格式。
3、User-Agent (简称 UA)
表示浏览器/操作系统的属性. 形如
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/91.0.4472.77 Safari/537.36
大概认识一下:(Windows NT 10.0; Win64; x64) windows10,64位,(Chrome/91.0.4472.77 Safari/537.36)当前浏览器Chrome 浏览器版本 Safari/537.36
UA是一个非常有用的字段,在以前浏览器只可以显示文字图片,后面网页丰富了,可以显示视频、音频,不过并不是全部浏览器都可以正常播放,网站开发者可以根据HttP请求的UA来锁定浏览器具体型号,开发者就知道能否可以放视频,如果能就返回视频,如果不能就返回不带视频的页面,这样做到了兼容性。
现在的UA不像以前那么有意义,但是现在主要是区别请求是移动端,还是pc端。
不过现在更主流的做法是采用“响应式布局”,在页面css中通过“媒体查询”功能根据屏幕的尺寸自动设置不同的样式,来兼容不同的设备。
4、Referer
表示这个页面是从哪个页面跳转过来的. 形如
如果当前的页面是直接输入url或者是在收藏夹点击链接此时Referer是空的。
如果你百度搜索,然后点击网站就会有从哪里来
那么Referer有什么用呢??
当我们点击网站广告,就会有是从什么搜索引擎过来的,这样搜索引擎就可以赚钱,结束的时候,就可以看看这个搜索引擎带来了网站多少的访问,可以和广告主结账统计,广告主的统计就根据Referer来统计。
5、Cookie
Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服
务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据).
往往可以通过这个字段实现 “身份标识” 的功能.
Cookie里面看起来是一些键值对结构~
键值对之间使用;号分割, 键值直接使用=分割,Cookie里的键值对表示的含义都是程序员自己自定义的。
cookie机制存在的目的,为了能够在浏览器这一段,保存程序员自定义的数据。
那么有人会问可不可以把存的数据保存在客户端浏览器所在的主机的硬盘上(存个文件)
当然是不可以的,浏览器为了保证安全性,禁止网页中的代码访问主机的硬盘~~(无法在js读写文件)
就让端开发失去了持久化存储的能力(但是很有必要)
虽然浏览器不让程序员去操作客户端的文件,,但是也提供了一个cookie这样的机制,按照键值对存储,来代替直接访问文件,这个cookie的内容是浏览器管理的(本质也是保存在硬盘)会持久化存在。
如果不是浏览器对于访问文件有限制,其实就不必要存在cookie 。
如果浏览器可以访问本地文件,那么你打开一个不知名的小网站,网页直接在给你硬盘写个病毒程序,你电脑就挂了。。
cookie就是浏览器提供一个让程序员在客户端这边持久保存数据的一种机制!!! 至于是什么完全看程序员怎么定义。
- cookie是什么?
cookie是浏览器提供的一种让程序员在本地存储数据的能力。
- cookie里面存的是什么?
cookie里存的是键值对格式的数据,键值对之间使用;分割,键和值之间使用=分割。
- cookie从哪里来?程序员如何往cookie里存东西?
每一个这个就是键值对
cookie在浏览器这边是按照域名维度来分别存储的。
baidu.com 有一组cookie,是百度程序员定义的,百度网站使用的
sogo.com 有一组cookie,是搜狗程序员定义的,搜狗网站使用的
在抓包我们可以看见这样的响应set-cookie header头
和cookie对应起来了
浏览器里存储的cookie都是从服务器的响应报头里面的set-cookie字段中来的,每个set-cookie字段包含一个cookie的键值对,浏览器拿到这个响应之后,就会吧set-cookie中的内容给保存到本地. set - cookie就是程序员在服务器代码中填写构造。
- Cookie要到哪里去?(谁来使用)
cookie字段会在后续的请求中,把浏览器本地存储的这些键值对,再发回给服务器(服务器端的代码来使用cookie)
来自服务器,返回服务器。
大家可以试试把网站的登录cookie删除然后重新登陆,要重新输入密码。
到今天2022年,cookie是唯一浏览器本地存储的机制吗?并不是的
浏览器提供了其他的本地存储机制
- LocalStrorage这个是HTML5开始,浏览器提供的一种新的本地存储的机制,只用这个完成可以代替cookie。
- indexDB这个是更新的一个东西,浏览器提供了一组类似于SQL这样的接口,可以在浏览器本地以类似数据库的方式存储数据
Cookie的缺陷:每次请求都要把该域名下所有的cookie通过HTTP请求传给服务器。这就注定Cookie的存储是有限的,相比之下新机制没有这个问题。
五、HTTP 响应详解
1、认识 “状态码” (status code)
状态码表示访问一个页面的结果. (是访问成功, 还是失败, 还是其他的一些情况…)
表白之后,妹纸会给你返回一个结果
- 好的我愿意
- 你是个好人
以下为常见的状态码.状态码是一个3位数的整数
200 OK
这是一个最常见的状态码, 表示访问成功
404 Not Found
没有找到资源.
403 Forbidden
表示访问被拒绝. 有的页面通常需要用户具有一定的权限才能访问(登陆后才能访问). 如果用户没有登陆
直接访问, 就容易见到 403
405 Method Not Allowed
前面我们已经学习了 HTTP 中所支持的方法, 有 GET, POST, PUT, DELETE 等.
但是对方的服务器不一定都支持所有的方法(或者不允许用户使用一些其他的方法).
500 Internal Server Error
服务器出现内部错误. 一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)会产生这个
状态码.
咱们平时常用的网站很少会出现 500 (但是偶尔也能看到)
504 Gateway Timeout
当服务器负载比较大的时候, 服务器处理单条请求的时候消耗的时间就会很长, 就可能会导致出现超时的
情况
这种情况在双十一等 “秒杀” 场景中容易出现, 平时不太容易见到.
302 Move temporarily
临时重定向
理解 "重定向"
就相当于手机号码中的 “呼叫转移” 功能.
比如我本来的手机号是 186-1234-5678, 后来换了个新号码 135-1234-5678, 那么不需要让我的朋
友知道新号码,
只要我去办理一个呼叫转移业务, 其他人拨打 186-1234-5678 , 就会自动转移到 135-1234-5678
上
在登陆页面中经常会见到 302. 用于实现登陆成功后自动跳转到主页.
响应报文的 header 部分会包含一个 Location 字段, 表示要跳转到哪个页面
例如: 码云的登陆页面 https://gitee.com/login
抓包看到的响应结果:
HTTP/1.1 302 Found
Date: Thu, 10 Jun 2021 06:49:26 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Keep-Alive: timeout=60
Server: nginx
X-XSS-Protection: 1; mode=block
…
301 Moved Permanently
永久重定向. 当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址.
301 也是通过 Location 字段来表示要重定向到的新地址
状态码小结
2、认识响应 “报头” (header)
3、Content-Type
响应中的 Content-Type 常见取值有以下几种:
- text/html : body 数据格式是 HTML
- text/css : body 数据格式是 CSS
- application/javascript : body 数据格式是 JavaScript
- application/json : body 数据格式是 JSON
4、通过 form 表单构造 HTTP 请求
form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET 或者 POST 请求.
不要把 form 拼写成 from!!
4.1、form 发送 GET 请求
form 的重要参数:
- action: 构造的 HTTP 请求的 URL 是什么.
- method: 构造的 HTTP 请求的 方法 是 GET 还是 POST (form 只支持 GET 和 POST)input 的重要参数:
- type: 表示输入框的类型. text 表示文本, password 表示密码, submit 表示提交按钮.
- name: 表示构造出的 HTTP 请求的 query string 的 key. query string 的 value 就是输入框的用户输入的内容.
- value: input 标签的值. 对于 type 为 submit 类型来说, value 就对应了按钮上显示的文本
<form action="http://sogo.com/" method="GET">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
页面展示的效果:
在输入框随便填写数据,点击 “提交”, 此时就会构造出 HTTP 请求并发送出去.
- form 的 action 属性对应 HTTP 请求的 URL
- form 的 method 属性对应 HTTP 请求的方法
- input 的 name 属性对应 query string 的 key (userid)
- input 的 内容 对应 query string 的 value(123)
4.2、form 发送 POST 请求
代码把get变成post
<form action="http://sogou.com/" method="post">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
body里面的数据,get在querystring里面 post在body里也是输入框的值
这个内型决定了我们是以键值对形式来进行
4.3、通过 ajax 构造 HTTP 请求
从前端角度, 除了浏览器地址栏能构造 GET 请求, form 表单能构造 GET 和 POST 之外, 还可以通过 ajax
的方式来构造 HTTP 请求. 并且功能更强大
ajax 全称 Asynchronous Javascript And XML, 是 2005 年提出的一种 JavaScript 给服务器发送
HTTP 请求的方式.
特点是可以不需要 刷新页面/页面跳转 就能进行数据传输.
同步:当你去买2个东西,你必须买完第一个东西,才可以去买第二个
异步:当你去买面,又想去买包子,你可以先叫老板娘做着,自己去隔壁包子铺买包子
在 JavaScript 中可以通过 ajax 的方式构造 HTTP 请求
先引入:
可以引入jquery cdn源:
cdn也是互联网中的一种基础设施,这是一组服务器 ,服务器是由运营商提供,存在的目的是为了加快用户的访问速度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
//$是一个变量名 是jquery定义好的一个对象 jquery里面的各种方法都是这个对象的成员
$.ajax(
url:'http://42.192.83.143:8080/AjaxMockServer/info',
method:'GET',
success:function(data,status)
//data响应的body
//status响应的状态
console.log(data);
);
</script>
</body>
</html>
图解:
那么有没有可能ajax可以来实现爬虫呢?
这个是不可以,因为ajax里面有限制是不可以跨域的
因为ajax是通过js代码触发的,js代码又是在一个html里面,访问这个html就有一个域名,ajax构造也有一个域名,就有2个不一样的域名了,必须要域名1和域名2一样才可以实现,如果要写一个抢票系统此时域名1和域名2 (12306)不在同域不可以跨,重复自己的服务器打开跨域。
不仅仅是ajax和form可以构造请求,任意编程语言,只要是能访问的网络,就可以构造HTTP请求,java也可以!(这个以后在写文章说)
六、认识HTTPS
1、HTTPS 是什么
现在互联网上,越来越多的网站,都是HTTPS的,也是基于HTTP(报文格式都一样),在HTTP的基础上,引入了一个加密层,SSL\\TLS.
HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层.
HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现一些被篡改的情况.
臭名昭著的 "运营商劫持"
下载一个 天天动听
未被劫持的效果, 点击下载按钮, 就会弹出天天动听的下载链接.
已被劫持的效果, 点击下载按钮, 就会弹出 QQ 浏览器的下载链接
由于我们通过网络传输的任何的数据包都会经过运营商的网络设备(路由器, 交换机等), 那么运营商的网
络设备就可以解析出你传输的数据内容, 并进行篡改.
点击 “下载按钮”, 其实就是在给服务器发送了一个 HTTP 请求, 获取到的 HTTP 响应其实就包含了该 APP
的下载链接. 运营商劫持之后, 就发现这个请求是要下载天天动听, 那么就自动的把交给用户的响应给篡
改成 “QQ浏览器” 的下载地址了
那么我们要怎么保证安全呢?HTTP不安全的根本原因在于“明文传输”,要想安全,就得加密
2、“加密” 是什么
加密就是把 明文 (要传输的信息)进行一系列变换, 生成 密文 .
解密就是把 密文 再进行一系列变换, 还原成 明文 .
在这个加密和解密的过程中, 往往需要一个或者多个中间的数据, 辅助进行这个过程, 这样的数据称为 密
钥 (正确发音 yue 四声, 不过大家平时都读作 yao 四声) .
3、HTTPS 的工作过程
既然要保证数据安全, 就需要进行 “加密”.
网络传输中不再直接传输明文了, 而是加密之后的 “密文”.
加密的方式有很多, 但是整体可以分成两大类: 对称加密 和 非对称加密
3.1引入对称加密
对称加密其实就是通过同一个 “密钥” , 把明文加密成密文, 并且也能把密文解密成明文.(加密使用的密钥和解密使用的密钥是同一个)
一个简单的对称加密, 按位异或
假设 明文 a = 1234, 密钥 key = 8888
则加密 a ^ key 得到的密文 b 为 9834.
然后针对密文 9834 再次进行运算 b ^ key, 得到的就是原来的明文 1234.
(对于字符串的对称加密也是同理, 每一个字符都可以表示成一个数字)
当然, 按位异或只是最简单的对称加密. HTTPS 中并不是使用按位异或.
引入对称加密之后, 即使数据被截获, 由于黑客不知道密钥是啥, 因此就无法进行解密, 也就不知道请求的
真实内容是啥了.
但事情没这么简单. 服务器同一时刻其实是给很多客户端提供服务的. 这么多客户端, 每个人用的秘钥都
必须是不同的(如果是相同那密钥就太容易扩散了, 黑客就也能拿到了). 因此服务器就需要维护每个客户
端和每个密钥之间的关联关系, 这也是个很麻烦的事情
比较理想的做法, 就是能在客户端和服务器建立连接的时候, 双方协商确定这次的密钥是啥
但是如果直接把密钥明文传输, 那么黑客也就能获得密钥了~~ 此时后续的加密操作就形同虚设了.
因此密钥的传输也必须加密传输!
但是要想对密钥进行对称加密, 就仍然需要先协商确定一个 “密钥的密钥”. 这就成了 “先有鸡还是先有蛋”
的问题了. 此时密钥的传输再用对称加密就行不通了.
就需要引入非对称加密.
3.1非对称加密
非对称加密要用到两个密钥, 一个叫做 “公钥”, 一个叫做 “私钥”.
使用公钥来加密,私钥来解密
也可以私钥加密,公钥解密
- 首先服务器自己生成一个公钥私钥密钥对,公钥公开出去,谁都可以获取(黑客也可以拿到)私钥自己保存(不让别人知道)
- 客户端拿到公钥之后,使用公钥,对对称秘钥进行加密,把加密后的密钥密文通过网络传输给服务器
- 黑客可以获取到这里的密文,但是黑客只有公钥,没有私钥,公钥加密,私钥解密,黑客拿到也无法解密,只有服务器自己有私钥才可以解密,这样就安全到达服务器了
- 后续客户端之间就可以使用对称秘钥钥进行加密解密了
如下图:
另一个重要的问题:
已经引入非对称加密了,为什么还要有对称加密,对称加密的成本(对机器资源的消耗)是远远低于非对称加密的
那么接下来问题又来了:
客户端如何获取到公钥?
客户端如何确定这个公钥不是黑客伪造的?
4、引入证书
在客户端和服务器刚一建立连接的时候, 服务器给客户端返回一个 证书.
这个证书包含了刚才的公钥, 也包含了网站的身份信息.
这个证书就好比人的身份证, 作为这个网站的身份标识. 搭建一个 HTTPS 网站要在CA机构先申请
一个证书. (类似于去公安局办个身份证).
这个 证书 可以理解成是一个
- 证书发布机构
- 证书有效期
- 公钥
- 证书所有者
- 签名
- …
当客户端获取到这个证书之后, 会对证书进行校验(防止证书是伪造的).
- 判定证书的有效期是否过期
- 判定证书的发布机构是否受信任(操作系统中已内置的受信任的证书发布机构).
- 验证证书是否被篡改: 从系统中拿到该证书发布机构的公钥, 对签名解密, 得到一个 hash 值(称为数据摘要), 设为 hash1. 然后计算整个证书的 hash 值, 设为 hash2. 对比 hash1 和 hash2 是否相等. 如果相等, 则说明证书是没有被篡改过的.
5、完整流程
HTTPS工作流程
- 对称加密,用于传输的数据进行加密(请求,响应)需要有一个对称密钥,客户端生成,要告知服务器
- 非对称加密,服务器提供一个公钥(服务器自己持有一个私钥),客户端使用公钥对对称密钥加密,密文传输给服务器
- 中间人攻击,黑客可能劫持了服务器给客户端的公钥,用自己生成的公钥代替,从而导致对称密钥的泄露
- 为了解决中间人攻击,引入了证书机制,通过第三方工证机构,向网站颁发证书,证书里面就包含公钥,客户端向服务器请求的就是证书,客户端那着证书去公证机构进行验证,看看证书是否合法。
面试最经常问HTTPS问题的就是上面的4步过程,准确来说这个过程就是SSL/TLS的一个流程,而SSL/TLS不仅仅使用在HTTPS中,也在很多其他地方会用到
以上是关于HTTP协议HTTP协议初体验,深入浅出网络协议的主要内容,如果未能解决你的问题,请参考以下文章