【JavaEE】网络(6)
一、http相关概念
1.1 什么是http协议
http协议(超文本传输协议),是应用层的一个协议
1.2 应用场景
- 网页与服务器之间交互
- 手机app与服务器之间交互
http协议是典型的一问一答模式的协议,即请求和响应是一一对应的
二、http协议格式
2.1 抓包工具——FIddler
抓包工具的作用就是能够获取网络上传输的http数据,并显示出来,抓包工具有很多,很典型的一个就是Fiddler,下述为其页面
- 页面左侧为所有http请求与响应,点击即可查看详情
- 右侧上方为http请求的报文格式
- 右侧下方为http请求的报文格式
2.2 抓包工具原理
抓包工具相当于一个代理程序,浏览器要访问服务器,Fiddler会抓到这个http请求,然后发给服务器,服务器返回响应,Fiddler也会抓取这个http响应,然后发给浏览器
注意:
- 代理程序不止有抓包工具,还有其他类型的抓包工具,比如:游戏加速器
- 代理程序之间会冲突,若要抓包,确保其他代理程序关闭
2.3 http请求格式分析
Fiddler的右上窗口就是http请求的报文格式,假如访问bing
首行:
- 方法:请求的方法,描述这个请求要干什么,下面详细解释
- url:网址
- 版本:http协议版本
Header:请求报头,都是键值对,键值之间以冒号分隔,每组键值对以\n分隔,到第一个空行代表Header结束
Body:正文,空行以下的部分,相当于载荷,Body不仅仅是html数据,也有可能为空,get请求中通常为空,如果Body不为空,则在Header中会有⼀个Content-Length属性来标识Body的长度
2.3.1 url详解
url基本格式:
https://cn.bing.com/search?q=%E4%BD%A0%E5%A5%BD&form=QBLH&sp=-1&lq=0&pq=%E4%BD%A0%E5%A5%BD&sc=11-2&qs=n&sk=&cvid=41094B30C53846FB9AA29ECE0CF8B52D&ghsh=0&ghacc=0&ghpl=
- https:协议方案名,描述url要干什么,常见的有http和https
- user:pass:登录信息,现在的网站一般通过登录页面来验证,一般不通过url的方式,所以这部分经常省略
- cn.bing.com:域名,确定访问的主机
- 端口号:用来确定访问主机上的哪个程序,上述url中端口号被省略,当省略端口号的时候,浏览器会根据协议类型自动决定使用哪个端口,例如http的默认端口是80,https是443
- /search:带层次的文件路径,确定访问程序中的哪个资源,通过IP地址确定主机,通过端口号确定程序/进程,通过文件路径确定资源,上述三者可以确定互联网的唯一一个资源
- 上述url中问好后面可以看到一个个键值对,键和值之家以=分隔,每组键值对之间以&分隔,这些是查询字符串(query string),表示一些参数,是客户端要告诉服务器的数据
url encode:
url中这些字符:/、:、?在url中有着特殊的意义,不能随意出现,如果在query string中的value部分出现了这些字符,url就会解析失败,为避免这种情况,url就引入了encode机制:针对键值对中的value进行转义
转义的规则如下:将要转码的字符转换为16进制(如果是字符,就是acsii码值,如果是汉字,就是utf8)之后在每个字符的16进制的前面加上%,编码成%XY的形式
2.3.2 方法详解
方法,描述了请求要干什么,用的最多的两个是GET 和 POST
① GET 和 POST 有什么区别(面试题)
- GET 和 POST 本质上没有区别,GET的应场景,POST也可以用,POST的应用场景,GET也可以用
- 从语义上,GET用来获取数据,POST用来发送数据
- GET一般通过query string 传输数据,POST一般通过body传输数据
- 服务器对于GET请求的设计经常是幂等的,而POST不是;
GET请求通产是幂等的:多次发送相同的GET请求,返回的数据是相同的,不会改变服务器上的资源的状态,比如查看一篇博客,点进去再退出再点进去,每次点进去这个文章都不会变 - GET请求的结果可以被缓存,比如通过GET获取的图片,浏览器可以缓存这些图片,下次访问的时候,直接从缓存中来读取(缓存再硬盘上),POST一般不行
② 针对GET 和 POST的一些错误说法
- POST安全,GET不安全:关于安全不安全,主要取决于加密操作(后面讲到https会讲),并不是参数写到body里就安全(因为可以抓包),也不是参数写到query string就安全
- GET传输的数据有限,POST传输的数量没有限制:在http标准中明确指出GET请求的URL没有长度限制,也就是query string没有长度限制
- GET只能传输文本数据,POST可以传输文本,也可以传输二进制数据:url提供了encode机制,二进制数据可以进行encode得到转义,并进行传输;POST虽然可以直接传二进制数据,但很多时候也是转义了之后通过文本的方式来传的
2.3.3 请求报头详解
- Host:标识服务器主机上的IP和端口号,一般和URL中的域名相同
- Content-Length:描述了body的长度,通过这个字段就可以避免粘包问题:通过空行可以知道body从哪开始,通过该字段可以知道body到哪结束
- Content-Type:描述了body的数据类型,常见的有下面两种
1. application/x-www-form-urlencoded:form表单提交数据,此时body格式如下:
title=test&content=hello
2. application/json:数据为json格式,此时body格式如下:
{"username":"123456789","password":"xxxx","code":"jw7l","uuid":"d110a05ccde64b16"}
- User-Agent(简称UA):表示浏览器/操作系统的属性
- Mozilla:是一个开源组织
- Windows NT 10.0; Win64; x64:表示操作系统的信息
-
AppleWebKit/537.36:表示浏览器的内核
-
浏览器内核后面的属于浏览器的其他信息
UA两个作用:
1. 告诉服务器,用户使用的是什么浏览器和该浏览器版本,有助于服务器提供与客户端兼容的内容
2. 让服务器知道用户使用的什么设备,如果是手机,就返回一个较小的页面;如果是电脑,就返回一个较大的页面
- Referer:表示这个页面是从哪个页面跳转过来的
上图就表示是从百度的某个页面跳转过来的
该字段主要用于广告业上,广告主可以根据这个属性知道哪个平台的流量高
- Cookie:Cookie是浏览器本地存储数据的一种机制,cookie中保存的是一个一个键值对,这些键值对代表一些用户名、用户偏好、会话ID之类的信息,这些数据都是服务器返回的
工作原理:
当用户首次访问网站时,服务器生成一个Cookie,为用户创建一个唯一的会话ID,并将这个ID存储到刚刚创建的Cookie中,将这个Cookie返回给用户浏览器,此时浏览器就会将这个Cookie存储在硬盘的文件中,当用户后续访问网站时,浏览器会自动将这个Cookie发送给服务器,服务器通过读取Cookie中的信息,快速识别出用户身份,以便服务器对于该用户提供个性化服务
举个例子:自动登录
当用户首次访问网站并输入用户名和密码进行登录时,服务器会生成一个唯一的会话ID,并将其与用户的登录信息相关联,同时,服务器会创建一个包含该会话ID的Cookie,并将其发送给客户端浏览器
客户端浏览器接收到Cookie后,会自动将其保存在本地,在用户后续访问该网站时,浏览器会自动将之前保存的Cookie(包含会话ID)包含在HTTP请求头中发送给服务器。
服务器会维护一个会话表,用于存储用户的会话ID和相关信息,服务器会根据会话ID查询到用户身份,就可以对该用户提供个性化服务(夜间模式、背景等)
2.4 http响应格式分析
Fiddler的右下窗口就是http响应的报文格式,假如访问bing
首行:
Header:请求报头,都是键值对,键值之间以冒号分隔,每组键值对以\n分隔,到第一个空行代表Header结束(可以看到响应里有Set-Cookie字段)
Body:和http请求的格式基本一样
2.4.1 状态码详解
状态码 | 状态 | 说明 |
200 | 成功 | 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页 |
404 | 未找到 | 服务器找不到请求的网页。 |
403 | 禁止 | 服务器拒绝请求 |
405 | 方法禁用 | 禁用请求中指定的方法 |
500 | 服务器内部错误 | 服务器代码出现bug,无法完成请求 |
504 | 网关超时 | 服务器作为网关或代理,但是没有及时从上游服务器收到请求 |
302 | 临时重定向 | 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求 |
301 | 永久重定向 | 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置 |
解释302:在访问某个旧地址的时候,自动跳转到新地址上,在登录的页面中,经常会见到302,用于实现登录之后自动跳转到主页
2.4.2 响应报头详解
响应报头的基本格式和请求报头基本一致.
响应中Content-Type的常见取值:
- text/html:body数据格式是HTML
- text/css:body数据格式是CSS
- application/javascript:body数据格式是JavaScript
- application/json:body数据格式是JSON
三、https协议
https 也是一个应用层协议,在http的基础上引入了一个加密层
3.1 核心概念
- 加密:将明文(要传输的原始数据)经过一系列转换生成密文
- 解密:将密文经过一些列变换还原成密文
- 密钥:进行加密和解密用到的重要道具
https就是通过加密操作来保证安全的,接下来介绍两种加密操作
3.2 对称加密
客户端和服务器使用同一个密钥对数据进行加密和解密
上图中客户端和服务器使用的是同一个密钥,该密钥就是对称密钥
服务器面对的是多个客户端,多个客户端可以使用同一个密钥吗?当然是不行的,因为客户端会提前和服务器约定好密钥是什么,那么黑客可以用自己的客户端获取到密钥,此时就知道了其他所有客户端的密钥了
所以每个客户端的对称密钥都必须不一样,客户端生成自己的对称密钥后,要告诉服务器,如果明文发送的话,也会被黑客截取,所以传输的时候要对称密钥进行加密,那就要提前生成一个密钥的密钥,仍然要告诉服务器,这样无法解决问题,所以引入非对称加密
3.3 非对称加密
非对称加密采用公钥和私钥两种密钥对数据进行加密和解密,服务器会将公钥告诉所有客户端(客户端并不是一开始就有公钥,而是连接上服务器后,服务器给客户端返回的公钥),私钥服务器自己会留着,每个客户端生成自己对称密钥后,会先使用公钥将对称密钥进行加密,然后发送给服务器
接下来是重点:使用公钥将对称密钥进行加密,但是只能使用服务器自己的私钥才能解密,私钥只有服务器拥有,所以即便黑客截取到了加密后的对称密钥也没办法对其解密(黑客只能获取到公钥)
服务器获取到数据后,先通过私钥解密获得对称密钥,再通过对称密钥解密获取原始数据
【中间人攻击】
非对称加密仍然存在不安全的要素,黑客无法获取到私钥,但他可以通过 "伪装" 的方式截取数据:
上图客户端与服务器建立连接,想要获取公钥,服务器返回公钥pub后被黑客截取,此时黑客自己会生成一对公钥pub1和私钥pri1,站在客户端的角度并不知道这个公钥已经被"掉包"了
此时客户端会采用pub1将自己生成的对称密钥进行加密并发送给服务器,黑客截取后,会使用自己的私钥pri1进行解密,最终获取到明文数据
黑客接下来会将数据使用服务器的密钥pub进行加密发送给服务器,这样在面对服务器,黑客伪装成客户端,面对客户端时,黑客伪装成服务器
接下来看如何解决中间人攻击问题
3.4 证书
上述问题的核心在于客户端无法辨认公钥是不是服务器发放的,所以为了让客户端有辨认能力就引入证书
服务器上线自己网站的时候,要先去第三方公正机构申请一个证书:
证书中包含一系列信息,比如:
- 发证机构
- 服务器的公钥
- 持有者网站的域名
- 证书的有效期
- 数字校验和
上述前四点的数据都是明文,而数字校验和是经过加密生成的:
第三方公证机构自己有一对公钥和私钥,将 校验和1 通过 公证私钥 加密得到 数字校验和
此时客户端和服务器建立连接就不会要公钥,而是要证书:
客户端拿到证书后,先对明文字段计算校验和,得到校验和A,然后对数字校验和进行校验,数字校验和是将校验和1通过公证私钥进行加密得到的,那么就需要公证公钥进行解密,获取公钥并不是通过网络获取的,而是在操作系统中内置了市面上所有第三方公证机构的公钥
客户端会根据证书中发证机构这个字段,来找到对应的公钥并对数字校验和进行解密,此时得到校验和B,如果校验和A和校验和B相等,则校验通过
【证书是否可以伪造?】
- 如果黑客修改了证书中服务器的公钥这个字段,而不修改数字校验和
此时客户端解密出来的校验和B和自己计算出来的校验和A不相同,则校验不通过 - 如果黑客修改了公钥,然后使用自己的私钥计算并修改了数字校验和
此时客户端是拿着系统内置的公钥去解密,肯定解密不了,所以校验不通过
🙉关于网络的篇章就到此结束