注意:本篇文章均基于 HTTP/1.1 的基础上讨论
简单:HTTP 报文的格式就是 Header + Body,消息头是 key-value 的形式,易于理解
灵活易扩展:HTTP 位于应用层,可以在应用层和传输层中间添加其它层来实现不一样的功能。HTTPS 就是在 HTTP 和 TCP 之间加了 SSL/TLS 安全传输层
跨平台性:不仅 PC 端,手机端也可以直接使用 HTTP 协议,具有天然的跨平台性
无状态:好处在于 HTTP 不需要去记录状态,减轻服务器负担;坏处在于关联请求处理起来非常麻烦,比如一些请求需要依赖于前面请求的状态,为此增加了 Cookie 技术
明文传输:好处在于 HTTP 报文便于阅读;坏处在于安全性极低,可以通过抓包等工具非法获取请求报文中的信息
安全性低:通过明文传输存在窃听的风险;无身份验证存在伪装的风险;无完整性验证存在篡改的风险
HTTP 基于 TCP/IP,使用「请求-响应」的通信模式,性能的关键就在这两个过程中
在 HTTP/1.0 中是短连接,每一次「请求-响应」都需要三次握手建立连接以及四次挥手断开连接
在 HTTP/1.1 中变成了长连接,也就是客户端和服务端建立连接后,直到客户端主动断开连接或长时间没有数据交互,在连接期间可以有多个「请求-响应」,减少了重复建立连接的开销
下面给出两种通信方式的过程:
虽然长连接避免了重复建立连接,但依旧只能同步的发送请求和返回响应。HTTP/1.1 中的管道网络传输类似于异步的发送请求,不需要等待响应结果的返回就可以继续发送下一条请求,过程如下:
这里给出两个概念
请求的队头阻塞:对于客户端发送请求到服务端,如果前一个请求的响应没有返回,那么当前请求就不允许发送,阻塞等待
响应的队头阻塞:对于服务端接收来自客户端的请求,必须按照顺序处理并响应,如果前一个请求还没有处理完毕,那么当前请求就不允许处理,阻塞等待
可以看出管道网络传输虽然解决了请求的队头阻塞,但依旧存在响应的队头阻塞
注意:实际上 HTTP/1.1 默认并没有开启管道网络传输技术,而且浏览器基本都没有支持该功能!!
安全性:HTTP 是明文传输,存在安全风险;HTTPS 是加密传输,在 HTTP 和 TCP 之间增加了 SSL/TLS 安全协议
建立连接:HTTP 三次握手后就可以开始传输报文;HTTPS 在三次握手后还需要进行 SSL/TLS 握手过程,保证传输的安全性
默认端口:HTTP 默认端口 80;HTTPS 默认端口 443
数字证书:HTTP 不需要数字证书;HTTPS 为了保证安全性需要先向 CA 机构申请数字证书,验证服务器的身份
在介绍 HTTP 安全性时,提到了三个问题:
窃听风险:由于 HTTP 是明文传输,可以轻轻松松截获网络中的报文并解析内容
篡改风险:在截获报文中插入新的内容,如:垃圾广告
伪造风险:冒充服务器,伪造报文
HTTPS 通过在 HTTP 和 TCP 之间增加 SSL/TLS 安全协议来解决上述三个问题,结构如下图所示:
更具体的,针对上面三个问题有以下解决方案:
信息加密:对传输报文加密,就算窃取也无法解密,主要采用混合加密的方式实现信息的机密性
校验机制:会对报文进行校验,被篡改的报文无法通过校验机制,主要采用摘要算法➕数字签名的方式实现信息的完整性
身份证书:在和服务器通信前,需要对服务器进行身份验证,主要采用数字证书的方式实现身份验证
首先给出两个概念
对称加密:加密和解密的密钥相同,必须确保密钥不会被第三方获取。对称加密运算速度快,密钥必须保密,无法做到安全交换密钥
非对称加密:加密和解密的密钥不同,分为公钥和私钥,可以使用公钥加密,私钥解密,也可以使用私钥加密,公钥解密。非对称加密运算速度慢,公钥无需保密,但私钥必须保密
非对称加密的两种不同加解密方式适用于不同的场景:
公钥加密,私钥解密:适用于消息传递,发送方通过公钥加密,只有拥有私钥的人才可以解密得到消息
私钥加密,公钥解密:适用于身份认证,发送方通过私钥加密,所有拥有公钥的人都可以确认发送者身份是否合法 (数字签名)
HTTPS 使用对称加密和非对称加密结合的方式 (混合加密):
在通信建立前采用非对称加密交换会话密钥,后续不再使用非对称加密
在通信过程中采用对称加密传输报文,密钥为非对称加密交换的会话密钥
如下图所示;
为了保证报文不被篡改,可以通过摘要算法计算出一个哈希值,然后将哈希值和报文一同发送到服务器,服务器再次对报文执行摘要算法,如果两次哈希值不同表示报文被篡改,如下图所示:
仅仅通过摘要算法将「内容 + 哈希值」一起发送并不能判断一定没有被篡改,如果内容和哈希值一起被篡改,那么最后比较的时候也是相同滴!!
所以我们可以使用非对称加密,用私钥加密哈希值,然后接收方通过公钥解密哈希值,最后判断内容是否被篡改,如下图所示:
为了防止其它人冒充服务器,需要对服务器的身份进行验证,每次通信前服务器都会将自己的公钥发送给客户端,那么如何判断该公钥就一定是请求服务器的公钥呢?
这里需要引入一个 CA 机构,它负责管理所有服务器的公钥,每个服务器都会把自己的公钥注册到 CA 机构中并生成数字证书,可认为 CA 机构中的公钥一定是合法滴
CA 机构会使用自己的私钥对服务器的公钥进行加密,服务器通信前会将数字证书发送给客户端,客户端获得数字证书后使用 CA 的公钥解密获得服务器公钥,如下图所示:
SSL/TLS 协议的基本流程:
客户端向服务器索要并验证服务器的公钥
双方协商产生会话密钥
双方采用会话密钥进行加密通信
前两步是 SSL/TLS 建立连接的过程,也被称为 TLS 握手阶段,主要涉及四次通信,使用不同的密钥交换算法,TLS 握手流程也会不一样,常用的密钥交换算法有:RSA 算法和 ECDHE 算法
基于 RSA 算法的 TLS 握手过程比较便于理解,所以先介绍它,流程如下图所示:
TLS 协议建立连接详细流程:
第一次握手:Client Hello
客户端向服务器发起加密通信请求
发送的信息主要有:客户端产生的随机数 C、客户端 TLS 版本、客户端支持的密码套件列表,如:RAS 加密算法
第二次握手:Server Hello
服务器收到客户端请求后,向客户端返回响应
返回响应的内容有:确定 TLS 协议版本,如果浏览器不支持则关闭加密通信;服务器产生的随机数 S;确认的密码套件列表;服务器数字证书
第三次握手:客户端回应
客户端收到服务器响应后,会确认服务器数字证书的真伪,如果证书没有问题就取出服务器公钥,使用公钥加密报文
客户端生成一个随机数 pre-master,使用客户端随机数 C、服务器随机数 S、随机数 pre-master 计算出会话密钥
客户端向服务器发送的信息主要有:pre-master;加密通信算法改变通知;客户端握手结束通知,将所有握手数据生成一个摘要
第四次握手:服务端回应
服务器收到客户端请求后,会获取 pre-master,同样的使用客户端随机数 C、服务器随机数 S、随机数 pre-master 计算出会话密钥
服务器向客户端响应的信息主要有:加密通信算法改变通知;服务器握手结束通知,将所有握手数据生成一个摘要
至此,TLS 四次握手过程结束,后续的通信使用握手过程中生成的会话密钥加密报文
模拟一种场景:客户端和中间服务器通信,中间服务器和目标服务器通信,中间服务器充当一个中间人的作用,从而可以窃取客户端的报文
客户端要和中间服务器通信,中间服务器必须向客户端发送自己的数字证书,此时客户端可以感知到中间服务器,浏览器会提示证书存在问题,用户可以手动选择是否信任该网站
所以从严格意义上来说,HTTPS 一定可靠,导致可能出现信息泄漏的风险是人为选择信任了中间服务器