HTTP、HTTPS详解
文章目录
- HTTP、HTTPS详解
- 一:HTTP超文本传输协议
- 1:HTTP协议的工作流程
- 2:URI和URL
- 2.1:DNS域名解析
- 3:HTTP报文的组成结构
- 3.1:请求报文
- 3.2:响应报文
- 3.3:HTTP报文字段
- 3.4:HTTP状态码
- 4:请求方法的分类
- 5:其他核心知识
- 5.1:长链接(持久连接)
- 5.2:HTTP代理技术
- 5.3:HTTP隧道代理
- 6:各个版本的缺陷和改进
- 二:HTTPS协议
- 1:SSL和TLS加密层
- 1.1:对称加密
- 1.2:非对称加密
- 1.3:数字签名,数字证书和CA机构
- 2:HTTPS的工作原理
- 3:TSL层握手过程(了解)
- 三:总结
- 四:附录
- 各个报文字段的内容
- 各个版本的缺陷和改进
一:HTTP超文本传输协议
HTTP
全称为Hyper Text Transfer Protocol
-> 超文本传输协议
HTTP协议是基于TCP
传输协议构建的应用层协议
作为支撑万维网www
的核心协议,为了保证其效率及处理大量事务的能力,因此在设计时,HTTP
被制定成为一种无状态协议
即HTTP本身不会对发送过的请求和相应的通信状态进行持久化处理
🎉 正因HTTP的无状态特征,所以在有些需要保持状态的场景中,则需要引入其他技术来实现,比如需要保持“登录状态、授权状态”时,需要配合Cookie来实现记录与管理状态
🎉 HTTP
于1990年提出后,经过多年的完善和扩展,目前已经存在多个主流版本的迭代:目前HTTP
主流应用版本还是HTTP/1.1、2.0
。
1:HTTP协议的工作流程
HTTP
核心由请求与响应构成,是一种典型基于客户端和服务器模型的协议
在目前的网络中,浏览器作为HTTP
协议的主要载体
一般来说,“从浏览器发出请求到服务器返回响应”,这个过程被称为一次HTTP
操作,也被称为一个事务,其具体过程如下:
https://i-blog.csdnimg.cn/direct/ba57af340dbb48e39da855445f5cffad.png" alt="在这里插入图片描述" />
从建立连接发出请求,到服务器处理完成后,返回响应再关闭连接,既代表着一个“事务”就完成了
但客户端接受到响应后,还会存在:解析响应报文、渲染结果数据这两步操作。
2:URI和URL
URI:资源标识符
URL:资源定位符
一般网络请求的前提是:需要用户在浏览器输入或点击超链接后,得到一个目标网址才会触发,而网址的专业术语为:URL
统一资源定位符,而URL
又是URI
的一部分。
但URI
统一资源标识符这个词并没有URL
那么普及,因此出现在大众视野中的次数并不多,它的作用是区分网络上不同的资源,主要涵盖了URL
和URN
两部分。
一般来说完整的URL
结构如下:
https://i-blog.csdnimg.cn/direct/6c6452bf463a4e2096c88019c0a083c8.png" alt="在这里插入图片描述" />
但上述结构使用较少,URL
的常用结构如下:
https://i-blog.csdnimg.cn/direct/9c62dc035aed4e5eaf87131a40f92d5f.png" alt="在这里插入图片描述" />
scheme
:表示使用的协议类型,例如http、https、ftp、chrome
等。://
:协议类型与后续描述符之间的分隔符。domainName
:网站域名,经DNS
解析后会得到具体服务器IP
。/path
:请求路径,代表客户端请求的资源所在位置,不同层级目录之间用/
区分。?query1=value
:请求参数,?
后面表示请求的参数,采用K-V
键值对形式。&query2=value
:多个请求参数,不同的参数之间用&
分割。#fragment
:表示所定位资源的一个锚点,浏览器可根据这个锚点跳转对应的资源位置。锚点也被成为片段标识符,#
部分之后的内容,即锚点不会被发送到服务器,锚点的作用仅是在浏览器解析时,跳转指定的位置显示
对比完整的
URL
,常用的URL
中除开用户名及密码外,还存在一点不同,即host:port
主机IP+端口变为了domainName
域名,那为什么又要这样做呢?
IP
不方便记忆,对于普通用户而言,一串数字远比不了“拼音缩写”,好比www.baidu.com
任何人都能记住,但14.215.177.38
却不行。- 服务器的
IP
是动态多变,当网关宕机后换机部署时,IP
又不相同了,但域名却是固定的,就算服务器IP
再怎么变,域名都不会更换。
2.1:DNS域名解析
在计算机网络中,每个主机都存在一个IP
地址,但由于IP
是一串数字不方便人类记忆,因此出现了一种协议名为DNS
DNS可以把生涩的IP
地址转换为便于人类记忆的域名,例如百度的:www.baidu.com
。
DNS(Domain Name System)
中文的意思是域名系统,每个互联网企业WEB
网站都可以看作是它自己在网上的门户,那么每个网站的域名就类似于“门牌号”
通常情况下,为了方便正常人记忆,域名都会使用公司的名称或简称,例如www.taobao.com、www.baidu.com、www.jd.com
等
因此当你要访问一个Web
网站,但又不知道其确切域名时,那么你首先可以输入其公司名称试试看。
因特网最开始仅由几百台计算机组成,因此最初的域名与IP
映射关系都是被保存在本地的Hosts.txt
文件中,每台因特网中的机器都从服务器上下载Hosts
文件,然后发送请求时就从本地查询IP
信息,但随着接入因特网的设备越来越多,因此原有的这种方式无法满足日益增长的因特网需求。
毕竟全球的设备都在不断的接入因特网,上网时都在使用域名访问,不过世界上并不存在一台DNS
服务器可以映射所有的IP
,所以域名系统最终被设计成了一个:带有层次结构的分布式K-V
数据库,整个DNS
由很多服务器共同组成的,大体结构如下:
https://i-blog.csdnimg.cn/direct/760b23855cf9449cb9f343c0b3bc0c60.png" alt="在这里插入图片描述" />
因特网上的域名服务系统也是按照域名的层次来划分的
每一个域名服务器都只对域名体系中的一部分进行管辖,DNS
服务器主要分为三类:
- 根域名服务器
TLD
顶级域名服务器- 授权域名(子域)服务器
除此之外,还存在一种本地DNS
服务器,但这个并不归纳在域名系统的分层结构中,不过本地DNS
服务器却是DNS
至关重要的一环。
DNS域名查询
DNS
中主要分为递归查询、迭代查询两种方式:
https://i-blog.csdnimg.cn/direct/2f753f5b5ee0441eacb8898389c08103.png" alt="在这里插入图片描述" />
递归查询的意思是指:客户端只需发出一次请求,就能得到相应的解析结果。
https://i-blog.csdnimg.cn/direct/e4a19bd6d4a345fe9c3f17e68b72542b.png" alt="在这里插入图片描述" />
DNS缓存
当然,上述过程无论是迭代还是递归查询,对于上层DNS
服务器而言,全球的访问压力都足以让其瘫痪,因此DNS
中还存在一个重要的概念:DNS
缓存:
- 本地
DNS
/非授权服务器缓存:各大运营商或大公司都有自己的DNS
服务器,一般部署在距离用户较近地方,代替用户访问核心DNS
系统,同时这些DNS
服务器可以缓存之前的查询结果,下次出现相同的DNS
解析请求时,可直接返回已缓存的IP
。 - 本地计算机DNS缓存:计算机本地缓存主要分为操作系统缓存与浏览器缓存两种:
- 浏览器缓存一般会有时间限制,如
Chrome
浏览器默认是1min
,一分钟内请求该域名,都会直接从本地缓存中获取IP
。 - 操作系统缓存是指本地的
hosts
文件,在浏览器中无法获取映射IP
时,会尝试从hosts
文件中获取。
- 浏览器缓存一般会有时间限制,如
🎉 主机和本地域名服务器之间的查询方式是递归查询
🎉 本地域名服务器和其他域名服务器之间的查询方式是迭代查询,防止根域名服务器压力过大,也就是代表着:一般情况下DNS
解析请求都采用先递归+后迭代方式。
DNS解析流程
- 客户端输入域名准备访问网站。
- 先查询「浏览器的
DNS
缓存」,命中直接向IP
发起访问,未命中继续往下。 - 继续查询「
OS
的hosts
文件」,如果仍然未命中,则向「本地域名服务器」发起「递归查询」请求。 - 「本地域名服务器」先查询自身缓存,未命中则向「根域名服务器」进行「迭代查询」:
- 「根域名服务器」返回「顶级域名服务器」的地址
- 「本地域名服务器」再根据地址向「顶级域名服务器」发起查询
- 「顶级域名服务器」返回负责该「域名」的「授权域名服务器」地址
- 「本地域名服务器」再根据地址向「授权域名服务器」发起查询
- 「授权域名服务器」返回「域名」的具体
IP
地址
- 「本地域名服务器」将
IP
返回给客户端并将「域名/IP
映射」缓存起来。 - 「浏览器」得到
IP
后,向其发出具体的「用户请求」,并将「域名/IP
映射」缓存。
https://i-blog.csdnimg.cn/direct/b9a913a4a17947ce9c62081ac326ca44.png" alt="在这里插入图片描述" />
3:HTTP报文的组成结构
3.1:请求报文
https://i-blog.csdnimg.cn/direct/062e5f627a594140a8c53a5a3a41231a.png" alt="在这里插入图片描述" />
请求行
请求行也被称为起始行,主要包含请求方法、资源路径以及协议版本三部分,具体如下:
GET /index.html HTTP/1.1
⚠️ 报文中每个不同的部位之间必须要用SP
空格隔开,末尾需要有一个CRLF
回车换行符,遵循ABNF
语法规范。
请求头
不管是请求头亦或是响应头,都可以算是HTTP
报文中最复杂的内容,因为其中可选字段是非常多的,一般来说头部字段遵循如下规范:
- 每个字段名与字段值以
K-V
键值对形式传递。 - 字段名不区分字母的大小写。
- 字段名中不允许出现非法字符,如空格、
/、&、^、_、@、}.....
- 字段名与字段值之间必须以
:
分割。
空行
必须存在,主要作用是用于区分请求头部和请求主体,也就是一个CRLF
回车换行符,用于告知服务器剩下的报文中不再含有头信息。
请求主体
也被称为HTTP
实体,在请求报文中被称为请求主体,这里主要描述用户的请求数据,可以是二进制数据,也可以是请求参数等等。
3.2:响应报文
服务器响应用户请求时,返回的报文被称为应答报文,大体结构如下:
https://i-blog.csdnimg.cn/direct/45e7fd728bb7439080191817759a44b7.png" alt="在这里插入图片描述" />
3.3:HTTP报文字段
头部存在很多可选字段,而HTTP
报文字段主要可分为五大类:
- 请求报文字段:支持
HTTP
请求的报文字段,用于请求头中。 - 应答报文字段:支持
HTTP
响应的报文字段,用于响应头中。 - 实体首部字段:描述
HTTP
实体内容的报文字段,可应用在请求主体与响应主体中。 - 通用报文字段:同时支持
HTTP
请求与响应的字段,即可用于请求头,也可用于响应头。 - 其他报文字段:并非在
HTTP
协议中定义的报文字段,但实际过程中经常使用的字段。
各个字段的具体内容可以参考附录
3.4:HTTP状态码
RFC
中规定了状态码必须要为三位数,其中第一个数代表了响应状态的类别,HTTP
中所有的状态码共被分为五大类别:
1xx/(Informational)
:信息性状态码,代表请求被成功接受,正在处理请求。2xx/(Success)
:成功状态码,客户端的请求被成功处理并返回。3xx/(Redirection)
:重定向状态码,请求的资源位置发生变动,需重新请求。4xx/(ClientError)
:客户端错误状态码,客户端请求出现错误导致请求失败。5xx/(ServerError)
:服务端错误状态码,请求的服务端内部错误导致请求无法处理。
牢记如上规则后,之后再看见状态码时,不管见没见过,都可以根据其首位数字推断出一个请求的大体状态,例如:
200
:以2
开头,代表请求成功,服务端正常接受并处理了该请求。301
:以3
开头,代表请求的资源位置发生变动,请求会被重定向,重新请求新位置。404
:以4
开头,代表客户端出现错误,请求的路径不正确导致服务端无法定位资源。500
:以5
开头,代表服务端出现错误,服务端在处理请求的目标资源时,执行过程出现错误。
4:请求方法的分类
HTTP/1.0
中提供了三个请求方法,HTTP/1.1
中新增六个请求方法:
GET
:一般用于获取资源数据,如获取用户信息、商品信息、首页数据等。POST
:一般用于传输/提交资源数据,如提交表单数据、提交字节数据等。HEAD
:向服务器发送类似于GET
方式的请求,但只要求返回头信息,不返回主体数据。PUT
:一般用于修改数据,向指定路径上的资源提交最新数据并将其全量替换。PATCH
:和PUT
方法类似,PUT
是全量更新,PATCH
可以只修改部分数据。DELETE
:一般用于删除资源/数据,如移除服务器上某文件资源等。OPTIONS
:列出请求的目标资源所支持的请求方法,用来跨域请求。TRACE
:追踪客户端请求/服务端响应路径,用于测试或诊断出错。CONNECT
:在与代理服务器通信时建立连接隧道,使用隧道进行TCP
通信。
其中最常用的是GET/POST
两种方式,其他的方法相对比而言,正常业务用的频率并不高。
Get和Post方法的区别
不同点 | get方式 | Post方式 |
---|---|---|
功能定义 | 获取数据 | 传输数据 |
传输数据方式 | URL中显式传参 | 隐式传参 |
允许传输的数据长度 | 传参长度有限 | 没有限制 |
总体执行效率 | 高 | 低 |
支持的传输格式 | 仅仅支持ASCII字符 | 整个ISO字符集 |
安全性 | 差(因为显式传参) | 高 |
浏览器缓存支持性 | 会被缓存,下次相同的会直接拿到 | 不会缓存 |
一次请求产生的数据包数量 | 只会返送一个TCP包 | 会分成两个包进行发送 |
资源获取方式 | 可以直接使用,因为可以读取缓存 | 需要重新请求(二次请求),因为不能读取缓存 |
5:其他核心知识
5.1:长链接(持久连接)
HTTP
是基于“请求/响应”模型所构建的协议,每次请求时,客户端和服务端之间都要新建立一个连接,服务端响应完成后又会立马断开连接。
这种方式带来的缺点很明显,频繁的创建/销毁TCP
连接造成的开销较大,资源浪费较多。
在HTTP
中为了解决频繁创建/销毁TCP
连接造成的开销,从而设计了一种Keep-Alive
(长连接/持久连接)模式
开启这种模式的情况下,可以复用已建立的TCP
连接
https://i-blog.csdnimg.cn/direct/8fc56cb10fb34970b63d497cdd4c2a02.png" alt="在这里插入图片描述" />
HTTP/1.0
中默认关闭,需要手动在请求头中添加Connection: Keep-Alive
才可开启HTTP/1.1
默认开启,可以手动添加Connection: close
关闭。
长链接并不是那么美好,对于服务器而言,会造成很大的并发压力,同时还存在一个经典问题:队头阻塞。
因为HTTP
协议事务处理机制中,要求对于请求的处理必须为“一求一应/一发一收”,所以HTTP
本质上会将请求串行化
所有的请求会被放入到一个队列中依次交由服务器处理
假设前面的请求任务执行时间过长,最终就会导致后面的所有请求全部被阻塞,因此这个问题就被称为队头阻塞。
https://i-blog.csdnimg.cn/direct/4d0c0920885d428c954662142d1ab85b.png" alt="在这里插入图片描述" />
解决队头阻塞问题的方案有两种:并发连接与域名分片
- 并发连接是指假设我们客户端同时建立多个连接,就会有多个串行化的通道,因此在客户端建立多个连接,可以增加队列数量,一个队列中的请求阻塞,并不会影响其他队列中的请求。【
Chrome
内核中默认允许一个域名下的并发连接值是6
个,Firefox
则是8
个】
https://i-blog.csdnimg.cn/direct/6bdc59e87e7841769fa00b13dd26861c.png" alt="在这里插入图片描述" />
- 区域分片是指一个域名可以支持多个并发连接,但如果开到了客户端的上限后,依旧无法满足需求会出现一定程度上的请求阻塞,此时我们可以多上几个域名,也就是可以多准备几个域名,然后域名配置的
IP
映射都指向同一台服务器,这样就可以支持更多的连接了
https://i-blog.csdnimg.cn/direct/12287ec1e1214507b31505284cb95a49.png" alt="在这里插入图片描述" />
5.2:HTTP代理技术
一般情况下,客户端和服务端之间的通信都是采用直连模式,即客户端解析域名后直接根据IP请求后端服务器,然后服务器处理客户端请求。
但这种模式下,假设后端节点出现故障宕机,那么整个系统则会陷入瘫痪。
同时这种模式,也无法解决部署后端节点的服务器性能瓶颈问题
因此为了确保系统更高的可用性和稳定拓展性,此时则可以加入 HTTP
代理。
代理的主要含义是指:在客户端与服务端之间假设一个节点,从而能够满足开发过程中的更多需求,如动静分离、负载均衡、服务高可用、网站安全等,大体示意图如下:
https://i-blog.csdnimg.cn/direct/977b4b8bf04c472da6c60a3b46a1d969.png" alt="在这里插入图片描述" />
代理服务器目前市面上也存在多种选择,如Varnish、Squid、Nginx
等,这些代理服务器的工作模式又可被分为正向代理和反向代理。
正向代理
正向代理是指客户端可以感知到“代理角色”的存在
客户端发送请求时需要指定目标服务端,然后代理服务器会将客户端的请求发送到目标服务器处理服务端处理完成后,代理服务器会接收响应结果并将其返回给客户端。
这样理解起来可能会存在些许抽象,那么例举生活中的例子:
“A喊B去楼下小卖部买包烟”,这个例子中“A”是客户端,“B”是代理服务器,“小卖部”是服务端。
“A”显然知道有“代理人”的存在,并且明确指定了目标,但“小卖部”却无法知道具体要买烟的人是谁,这就可以理解为“正向代理”。
反向代理
==代理服务器的存在对于客户端而言,是无法感知的。==简单来说,就是指用户在访问代理服务器就跟直接访问服务器一样。
当用客户端根据域名解析IP
访问时,其实解析得到的是反向代理服务器所在的机器IP
当客户端请求发送到反向代理服务器时,代理服务器会将请求分发到具体的“服务端机器”上处理
服务端处理完成后会将数据返回给反向代理服务器,然后由代理服务器将结果响应给客户端。
https://i-blog.csdnimg.cn/direct/15313b65f4f4489eb87592b4d9b3604d.png" alt="在这里插入图片描述" />
5.3:HTTP隧道代理
之前的普通代理模式中,代理服务器是“中间人”的角色
此时假设需要传输HTTPS
流量,因为HTTPS
需要认证,但代理显然不可能有网站的私钥证书,最终就会导致客户端和代理之间的TLS
无法建立,证书校验无法通过。
HTTP tunnel
以及CONNECT
机制就主要解决了这个问题,代理服务器不再作为中间人,不再改写浏览器的请求
通过CONNECT
方法让客户端与任意目标服务器的IP
和端口建立一条TCP
连接
创建成功后,隧道代理在其中只负责将浏览器和服务器之间通信的数据原样透传
这样客户端就可以直接和远端服务器进行TLS
握手并传输加密的数据。
6:各个版本的缺陷和改进
https://i-blog.csdnimg.cn/direct/875f021244754edeba75fa43c11dd401.png" alt="在这里插入图片描述" />
具体的内容参考附录:各个版本的缺陷和改进
二:HTTPS协议
由于HTTP
协议是采用明文传输的方式,因此带来了很大的数据安全隐患
在最近几年的时间内,大部分平台都采用了HTTPS
逐渐取代了HTTP
HTTPS
是建立在HTTP
协议的基础之上,为其添加了一层TLS/SSL
,从而实现数据的加密传输,确保足够的安全性,二者区别如下
https://i-blog.csdnimg.cn/direct/ddf77d7a3df74c38bab5409d44f6638b.png" alt="在这里插入图片描述" />
相较于HTTP
而言,HTTPS
则拥有更高的安全性,例如数据加密传输、报文完整性效验、身份认证判断等。
解决了HTTP
协议中一直存在的安全问题,如:
- 明文传输数据会遭受窃听风险
- 不验证报文完整性会导致数据被篡改
- 不效验通信方身份会导致“他人”伪造通信对端劫持客户端
- …
1:SSL和TLS加密层
在HTTPS
中最关键的是数据安全传输,而负责这块的则是SSL/TLS
层
该层中的功能实现主要依赖于三类加密算法:哈希散列加密、对称加密及非对称加密算法,其中常用的算法如下:
- 哈希散列加密算法:
MD5、SHA1、SHA256
等。【单向加密,无法解密】 - 对称加密算法:
AES-CBC、AES-GCM、DES、3DES
等。【有密钥,可以加密和解密】 - 非对称加密算法:
RSA、DSA、ECC、DH
等。【双秘钥 - 公钥和私钥】
1.1:对称加密
https://i-blog.csdnimg.cn/direct/56e8f347a8b14cf2a5b82965ac0d2962.png" alt="在这里插入图片描述" />
⚠️ 这种方式存在天然的弊端,因为通信的双方都采用相同的加密方式,一般服务端与客户端通信都是1-N
的模式,那么一个客户端的加密方式被“破解”,就会导致所有客户端的数据都能够通过这种方式解密,从而被窃取真实数据。
1.2:非对称加密
对称加密算法在加/解密时采用的密钥都是相同的,而非对称加密算法则恰巧相反,非对称加密方式中存在两个密钥:公钥、私钥。
如果用公钥加密的数据,只有用对应的私钥才能解密;如果用私钥加密的数据,那只有用对应的公钥才能解密。
因为加/解密使用两个不同的密钥,最终则被称为:非对称加密。
首先生成两个密钥,将其一把作为公钥发送给所有客户端,另一把则当作私钥仅自己保存:
https://i-blog.csdnimg.cn/direct/ae4e04f1909c488e9b8d486f80636eab.png" alt="在这里插入图片描述" />
但是非对称加密也可能受到攻击者的攻击
- 服务端的真公钥返回经过攻击者的时候,攻击者用自己的公钥替换掉了服务端的公钥
- 客户端用假的公钥进行加密传输,攻击者用自己的私钥解密,然后用服务端的真公钥在进行加密
- 服务端防御真私钥的加密消息时候,攻击者用真公钥解密数据,然后用自己的假的私钥加密数据,返回自己的数据给客户端
https://i-blog.csdnimg.cn/direct/88c3b5055fb3472e877be5f42052f7f3.png" alt="在这里插入图片描述" />
其实这本质上是两个问题:
- 数据遭受篡改。这个问题发生的原因是:客户端没有效验数据完整性,因此对于对端发送的数据无条件信任,最终就导致了客户端无法区分数据究竟是第三者发出来的,还是真正的服务端返回的。
- 第三者将公钥掉包。这个问题的主要原因在于:客户端没有效验通信对端,即服务端的身份,因此无法区分传回的究竟是服务端,还是第三者的公钥。
1.3:数字签名,数字证书和CA机构
要解决上述中的两个问题,那必须从问题的根源「客户端」着手解决,该怎么解决呢?
可以引入数字签名、数字证书的概念。
数字签名主要防止了数据被篡改问题,数据证书解决了公钥被掉包问题。
「数字签名、数字证书」是从权威的第三方机构中申请的,这类机构被称为CA
机构申请流程一般为:
- 服务端先在本地生成一对密钥,然后携带公钥、网站信息、企业信息等数据去
CA
机构申请; CA
机构根据提交的信息核实身份后,会通过单向的哈希算法(如MD5
)对这些信息进行加密,加密后的内容被称为“信息摘要”,因为单向哈希算法的不可逆特性,所以只要被加密的内容发生了丁点改变,加密后得到的内容也会存在天差地别,因此可以有效防止信息被篡改;- 紧接着
CA
机构会通过自己的密钥对“信息摘要”进行再次加密,加密后的内容被称为「数字签名」,而「申请信息、服务器公钥、数字签名」组合在一起,最终被称为「数字证书」。
https://i-blog.csdnimg.cn/direct/2ee88d932c81440d8d298f46e808f2fc.png" alt="在这里插入图片描述" />
🎉 客户端OS
与浏览器中都会提前预装CA
机构的根证书,这些根证书中已包含了CA
公钥、当前CA
机构使用的Hash
算法等
由于数字签名是采用单向哈希算法,生成的“信息摘要”是不可逆的,当服务器返回的证书内容被篡改后,客户端在生成摘要比对时,结果肯定不匹配,因此客户端会拒绝连接。
但仅这样也无法避免公钥被掉包,也就是“第三者”也去CA
机构申请证书,然后在中间直接将整个证书替换成自己的,最终客户端获取的依旧是“第三者”的公钥
为了解决这个问题,CA
机构颁发的数字证书中,还会涵盖网站信息(如域名、所有者等),当证书被掉包后,客户端发现返回的证书与请求的网站信息并不同,那么依旧会拒绝连接。
经过上述一系列手段后,解决了非对称加密传输公钥时的不安全问题,但非对称加密方式,由于加/解密过程复杂,因此性能会比对称加密要低不少,因此在HTTPS
中是非对称加密与对称加密混合使用的模式,其中数据是对称加密方式传输的,而对称加密的密钥是通过非对称加密方式传输的。
2:HTTPS的工作原理
https://i-blog.csdnimg.cn/direct/9fc4b3e6703e46ba83a1b857352d484f.png" alt="在这里插入图片描述" />
- 客户端先向服务端请求公钥,其实就是与服务端
443
端口建立连接的过程。 - 服务端接收到请求后,会将数字证书返回给客户端。
- 客户端收到证书后,会进行校验操作,确认证书合法后,会先生成一个对称密钥,然后通过证书中的公钥对其加密,并发给服务端。
- 服务端收到公钥加密后的对称密钥后,通过自己的私钥对其解密。
- 最终客户端、服务端都拥有了一把对称密钥,接下来则通过对称密钥传输数据。
3:TSL层握手过程(了解)
实际HTTPS
的工作原理远比前面所赘述的流程复杂很多,接下来则详细阐述一下其中的TLS
握手过程。
TLS/1.2
之前的版本都是采用RSA
算法进行密钥交换,但TLS/1.2
及之后的版本中主要采用ECDHE
算法实现。
一般而言,TLS
层在交换密钥时都会经历多个步骤,其中可分为11
个小阶段,4
次握手阶段
三:总结
对比项 | HTTP | HTTPS |
---|---|---|
默认端口 | 80 | 443 |
传输模式 | 不安全的明文传输 | 安全的加密传输 |
使用成本 | 免费且谁都能用 | 需要花钱购买证书并核实身份 |
连接状态 | 无状态协议 | 有状态协议 |
握手过程 | TCP三次握手 | TCP三次握手+TLS四次握手(TLS/1.3三次) |
传输性能 | 基于TCP报文传输速度较快 | 数据传输需要加/解密,性能略低 |
资源标识 | URL上显示http:// | URL显示为https:// |
资源开销 | 仅维持自身开销即可 | 建立在HTTP 基础上,还需增加额外开销 |
四:附录
各个报文字段的内容
请求报文字段
客户端请求目标服务器时,可在请求报文头部中添加的字段:
Accept
:代表客户端支持的数据类型,可选项如下:- 文本类型:
text/html
:希望服务器返回HTML
类型的数据。text/plain
:希望服务器返回普通文本类型的数据。text/css
:希望服务器返回CSS
类型的数据。application/xml
:希望服务器返回XML
类型的数据。application/json
:希望服务器返回JSON
类型的数据。
- 图片类型:
iamge/jpeg
:表示希望返回.jpg
格式的图片。image/gif
:表示希望返回.gif
格式的图片。image/png
:表示希望返回.png
格式的图片。image/webp
:表示希望返回.webp
格式的图片。
- 视频类型:
video/mpeg
:希望服务器返回视频数据。video/quicktime
:希望服务器返回MAC
电脑的视频类型数据。
- 字节类型:
application/octet-stream
:希望返回字节流数据。application/zip
:希望返回ZIP
压缩字节数据。
*/*
:表示接受所有类型的数据返回。Accept
字段可设置多个值,服务器会依次进行匹配,会返回最先匹配到的数据类型。- 也可以通过参数
q
来设置权重,权重越高,优先级越高,取值范围0.000~1
,默认为1
。 - 例如
text/html,application/xml;q=0.9,*/*
,优先匹配HTML
数据,当服务器先匹配到XML
数据时,因HTML
权重高一些,因此会依然继续匹配HTML
数据。
- 文本类型:
Accept-Charset
:表示客户端支持的字符集,如GB2312,ISO-8859-1,UTF-8
等。Accept-Encoding
:表示客户端支持的内容编码格式,常用格式如下:gzip
:由gzip
压缩算法生成的压缩数据编码格式。compress
:由compress
压缩算法生成的压缩数据编码格式。deflate
:由zlib+deflate
压缩算法生成的压缩数据编码格式。identity
:默认的编码格式,表示不压缩数据。
Accept-Language
:表示客户端支持的语言语种,如zh-cn,en,zh
等。Authorization
:表示客户端的认证信息。Host
:表示客户端访问的目标资源所在的主机,即域名,如www.baidu.com
。Referer
:资源引用链,也称为防盗链,表示获取资源的请求来自哪个页面。If-Match
:实体标记,该值与请求的目标资源ETag
值一致时,服务器才受理该请求。If-Modified-Since
:效验客户端本地资源的时效性,如果本地的缓存资源没有超时则不处理请求。If-None-Match
:和If-Match
作用相反,该值与ETag
值不一致时才处理请求。If-Range
:If-Match
的升级版,访问的资源ETag
值或时间一致时,服务器处理此请求。If-Unmodified-Since
:If-None-Match
的升级版,与If-Range
作用相反。Max-Forwards
:最大传输逐跳数,也就是请求允许被转发的最大次数,转发一次就-1
。Proxy-Authorization
:客户端提供给代理服务器的认证信息。Range
:表示获取部分资源,如Range:bytes=50-800
,代表获取第50~800
字节之间的数据。User-Agent
:客户端程序的信息,一般情况为当前浏览器的简略信息。TE
:传输编码的优先级。..........
应答报文字段
客户端请求服务器后,服务器响应客户端时,应答报文中可出现的字段:
Accept-Ranges
:表示服务器是否接受按字节范围获取数据的请求。Age
:表示服务器创建响应资源的时间。ETag
:实体的标识,资源的匹配信息。Location
:告诉客户端资源的重定向位置/(URL
)路径。Proxy-Authenticate
:将代理服务器需要的认证信息返回给客户端。Retry-After
:请求失败后,告诉客户端多久后重试。Server
:告知客户端目前服务端的HTTP
服务器信息,一般为Nginx
。WWW-Authenticate
:客户端请求资源失败时,告知其目标资源所需的认证方案,如Basic、Digest
,一般配合401
使用。status
:客户端请求后的响应状态。Vary
:代理服务器的缓存管理信息。
实体首部字段
实体也就是指请求的目标资源,任何一个数据在HTTP
协议中都可被称为HTTP
实体:
Allow
:告知客户端所请求的资源支持的HTTP
方法,如请求方法错误会以405
状态返回。Content-Encoding
:告知客户端资源(实体)数据所采用的编码方式。Content-Language
:告知客户端资源所采用的自然语言,即zh-ch、en-US
等。Content-Length
:告知客户端资源的大小(字节长度)。Content-MD5
:告知客户端资源的报文摘要。Content-Location
:告知客户端资源所在的位置。Content-Range
:告知客户端资源接受按字节区域获取的范围。Content-Type
:告知客户端资源的数据类型。Expires
:告知客户端资源的过期时间。Last-Modified
:告知客户端资源最后一次的修改时间。
通用报文字段
通用报文字段是指可用于请求报文、应答报文、实体首部等多处位置的共享字段:
Cache-Control
:控制浏览器缓存的行为,常用选项如下:max-age=N
:请求到资源后将其缓存在本地,有效期为N
秒。no-cache
:协商式缓存,请求到资源后缓存到本地,后续每次请求资源时先与服务器确认是否更新过,更新则重新请求,否则从缓存中读取资源。no-store
:禁用浏览器本地缓存,每次从服务器上获取资源。max-age=N,must-revalidate
:请求到资源后将其缓存,有效期为N
秒,到期后再与服务器协商确认资源是否更新,未更新则延长有效期,否则重新获取。
Connection
:是否开启长连接,设为Keep-Alive
代表开启长连接。Date
:HTTP
报文的创建时间,使用格林威治标准格式。Pragma
:1.1
版本之前的历史遗留字段,为了兼容而设计的。Transfer-Encoding
:指定了报文主体传输时的编码格式,如Transfer-Encoding: chunked
。Upgrade
:用于检测协议版本,是否有其他更高的版本可用。Via
:追踪客户端和服务端之间的报文的传输路径,一般在使用代理服务器时必须要用的字段。Warning
:告知客户端一些与缓存相关的警告信息。
其他报文字段
其他报文字段是指并非在HTTP
协议中定义的字段,但依旧使用频率较为频繁的字段:
Cookie
:由于HTTP
是一种无状态协议,因此通常使用Cookie
也实现一些需要保持状态的功能,如身份Token
、登录信息等,一般用于请求报文中。Set-Cookie
:一般用于应答报文中,实现服务器给客户端传递Cookie信息,常用属性如下:Key=Value
:往客户端的Cookie
中写入值。expires=N
:设置客户端Cookie
的有效期。domin
:指定Cookie
生效的域名,只有请求该域名时才会携带Cookie
。path
:指定Cookie
生效的具体资源路径,只有访问该路径时才会携带。Secure
:设置该属性后,只有安全连接(HTTPS
)情况下才会保存Cookie
。SameSite
:在跨域时是否携带Cookie:Strict
:跨域时严禁携带本站Cookie
。Lax
:默认值,通过GET
方式访问之后可允许携带。None
:在设置了Secure
属性情况下,所有请求都允许携带。
HttpOnly
:使Cookie
不能被JS
脚本访问。
Content-Disposition
:主要用于文件上传与下载时指定操作和名称:- 上传时:
form-data
:以表单形式提交multipart
数据。
- 下载时:
inline
:将文件内容直接在网页上显示。attachment
:下载文件时弹出对话框让用户确认下载。
filename
:下载/上传时指定文件的名称。
- 上传时:
各个版本的缺陷和改进
HTTP/0.9
:仅支持GET
方式的纯文本请求。HTTP/1.0
:- 特点:无状态、无连接,支持多类请求方式,任意数据都可以传输。
- 缺点:每次请求时无法复用连接,需重新建立连接。
HTTP/1.1
:- 改进:
- 支持长连接(
Connection: keep-alive
)。 - 支持管道化请求。
- 支持缓存管理,分为强缓存和协商缓存两种。
- 支持断点续传。
- 支持一个
WEB
服务器创建多个站点(Host
)。 - 增加多个请求方法。
- 支持长连接(
- 不足:
- 传输性能有限,请求会发生阻塞(队头阻塞)。
- 改进:
HTTP/2.0
:- 改进:
- 引入新的二进制协议,应用层与传输层之间数据支持二进制分帧。
- 引入多路复用机制,提高连接可用性。
- 优化请求头,使用
HPACK
头部压缩算法避免传输重复头。 - 支持服务器主动向客户端推送资源。
- 不足:
- 因基于
TCP
协议构建,出现丢包时,整个会话需等待重传,后面数据会被阻塞。
- 因基于
- 改进:
HTTP/3.0
:- 改进:
- 抛弃
TCP
协议,转至基于UDP
协议构建的QUIC
协议(又称HTTP/3.0
)。 - 新增
0-RTT
机制:缓存当前回话上下文,下次恢复会话将缓存传给服务器验证后,即可传输数据。 - 优化多路复用机制:会话的多个流间不存在依赖,丢包只需重发包,无需重传整个连接。
- 针对移动端应用优化:由于之前基于
TCP
协议,因此对于移动端的IP
多变而言,非常影响传输,3.0
通过ID
识别连接,ID
不变,即可快速连接。 - 更好的安全性:
3.0
中几乎所有报文都要经过认证,主体经过加密,有效防窃听、注入和篡改。 - 提供向前纠错机制:每个数据包中携带部分其他数据包的数据,少量丢包可通过其他包的冗余数据直接恢复,无需丢包重传。
- 抛弃
- 改进: