--- Http和Https协议 ---
HTTP(全称为超文本传输协议)是一种使用非常广泛的应用层协议,往往是基于传输层TCP协议实现的
当我们在向服务器发起一个http请求时,比如http://leetcode.cn/problems/course-schedule/description/,TCP传输协议负责把响应发送回你的浏览器,而浏览器就安HTTP的格式解析这收到的响应格式,这样浏览器就认得到获取的响应了,并成功的把结果渲染出来到你的网页上
HTTP的具体格式
HTTP是一个文本格式的协议,可以使用fiddler抓包工具看到
请求头的HTTP格式

header部分
GET http://49.234.46.94:18888/chat/getHistoryMessage?sessionId=107 HTTP/1.1
第一行代表的是请求的方法和url 和 http的版本号1.1
剩下的这些是header的属性他对http信息进行了补充
host 请求的主机地址
connection 保持tcp连接复用
user-Agent 请求的浏览器标识,包含操作系统和浏览器版本信息
Accept 接受的响应的格式, */*表示接受任何形式的响应格式
Accept-Encoding 支持压缩格式
Accept-Language 偏好的语言种类
x-requested-with 表示以什么方式发起的请求,XMLHttpRequest 是ajax发起的请求
Referer 来源页面url,表示这个页面是通过其他页面跳转的
Cookie 会话凭证
还注意到 这个cookie下其实还有俩行空白的,而这http协议这寸土寸金的肯定不会留下无用的东西,这第一行表示的是这时请求头和请求体的分界线,而第二行空白的就代表的是请求体body了
响应

header部分
第一行 表示协议的版本号和响应状态码 这里为404就代表了经常看到的404 not found了
Content-Type 响应体的格式 这里application/json代表的就是json的格式
有些还有 Content-Length 代表了请求体的长度
Transfer-Encoding 表示传输的方式,chunked 表示使用的是分块式编码传输
Date 服务器生成响应的时间(格林尼治标准时间)
Keep-Alive 表示tcp连接保持活跃,超时时间为60s
Connection 连接状态,keep-alive 连接保持开放而不是在收到连接了直接给关闭了
空行下面的请求体
12e0 代表的是当前求块的请求十六进制的大小
接着的就是请求体的数据了
最后一行的0 代表数据块发完了,他实际的格式是0\r\n\r\n
URL
url的格式
http://21.444.32.94:18888/client_v2.html?userId=10001
协议 :// IP地址 : 端口号 / 请求的资源位置 ? 请求参数
URL encode
像/?:等这样的字符,已经被url当做特殊意义理解了,因此这些字符不能随意出现.
在写入url中的某些特殊字符会进行编译,对于汉字按utf-8进程编译,对于特殊字符按照ascll码表进行编译 通常是在%后面跟上对应的数字,会把要转码的字符转为16进制用%XY表示 比如A是%41
HTTPS
HTTP在文本传输中都是按照明文的方式传输的,这跟裸奔没啥区别了,因为发送的请求会经过其他路由器的转发,那么就极有可能被别人劫持并修改其中的信息,就比如你发起一个下载hh邮箱的链接,结果在经过一个路由器时,被检测出来了,给你替换成下载qq邮箱了, 那肯定不行,所以就搞了个加密版的HTTP叫做HTTPS
HTTPS是在HTTP的基础上加了一个加密的过程
加密的方式整体可以分为俩部分 对称加密和⾮对称加密
对称加密
在握手环节会确定使用的加密算法和密钥,之后与服务器之间的就可以使用这个密钥来进行加密传输,这样即使数据被劫持,但不知道数据的内容
但是因为密钥的传输是用明文传输的,如果在握手环节劫持了密钥,那么之后的数据加密也就形同虚设了,那么就需要对密钥在进行加密,可是这样服务器就不知道密钥是啥了,就成了个先有鸡还是先有蛋的问题了,那么要解决这个问题,就需要引入非对称加密了
非对称加密
在客户端和服务其中分别存在公钥和私钥俩对密钥,公钥是公开的,私钥是自己保存的不会流出的,在客户端在向服务器发起请求使用服务器公开的公钥来对请求数据进行加密,并且把自己的公钥也发送给他,在服务器收到请求之后,找到和这把公钥匹配的私钥,使用这个私钥来对数据进行解密,之后对服务器发送的响应,使用客户端的公钥来对数据进行加密,然后客户端使用对应的私钥来对数据进行解密,这样即使公钥被截取了,因为不知道私钥则仍然不能对数据解密
但这样也出现了中间人攻击的危险
中间人攻击
这里有中间人 公钥 私钥 m(M)服务器 s(S)
用户向服务器发起请求,服务器返回公钥 s
中间人截取到响应,把这个公钥给替换为自己的公钥 m, 并储存到s
用户不知道这个公钥被替换了,就使用公钥 m 把自己生成的对称密钥 X 给加密发送给了服务器
中间人截取到这个数据包,使用私钥 M 解密获取到了对称公钥 X 在使用曾经保存的公钥 s 加密数据 发送给服务器
之后双方就使用 X密钥 来进行对称加密通信
这样一趟下来,中间人就获取到了用户和服务器交流的对称加密密钥,就能对数据进行截取,修改
而为了解决中间人攻击,于是引入了证书
证书
服务端在使⽤HTTPS前,需要向CA机构申领⼀份数字证书,CA机构会对服务端进行审核,并使用CA的私钥专门为该网站生成一个数字签名,并和该申请者的申请明文一起就构成了数字证书,数字证书⾥含有证书申请者信息、数字签名、服务端公钥信息等, 服务端把证书发送给浏览器就好,浏览器会在证书中获取到公钥,证书就如身份证,证明服务端公钥的权威性
使用证书来解决解决中间人攻击
在用户请求获取公钥,服务器返回一个证书,这个证书包含了公钥和网站的信息,用户收到证书后会对证书进行验证
验证证书的时间是否过期
验证证书机构是否受信任,在系统中内置了受信任的证书机构
对获取证书计算出一个hash值,然后用CA公钥解密获取原始的数字签名,比较这俩个值是否相同,如果相同这证明没有被篡改过
而中间人如果篡改了证书,那么证书计算hash值就和数字签名就配不上,而如果他改了证书内的明文信息,但是没有CA的私钥,他并不能创建出对应的数字签名,还是能被客户端检测出来,而如果中间人有CA证书从而掉包整个证书的话,由于证书中包含该服务的域名和认证信息,那其实还是可以被客户端发现
所以https工作是涉及的密钥有三种
第一次(非对称加密): 客户端获取到证书,校验证书通过后获取到服务端公钥
第二次(非对称加密):协商对称加密的密钥,客户端使用这个公钥生成对称加密的密钥,发送给服务器
第三次(对称加密):之后就都使用整个对称加密公钥进行交流
