---
Http 与 Https
---

#### 目录

1. Http
2. Https
3. 缓存机制
4. 常见问题汇总
5. 参考

#### Http

Http 即超文本传输协议，是常见的应用层协议，其传输的内容都是明文的，不安全。

如果想要进行密文传输，就需要加密。

#### 加密方式

加密方式分为对称加密和非对称加密。

##### 对称加密

通信双方采用相同密钥进行加解密，即：

```java
encrpty(明文，密钥) = 密文
decrpty(密文，密钥) = 明文
```

##### 非对称加密

传输数据采用公钥加密，必须采用公钥对应的私钥才能解密，即：

```java
encrpty(明文，公钥) = 密文
decrpty(密文，私钥) = 明文
```

对称加密速度快，加密时 CPU 资源消耗少；非对称加密对待加密的数据的长度有比较严格的要求，不能太长，但是实际上消息可能会很长，所以用对称加密来加密数据。

#### 缓存机制

Web 缓存是一种保存 Web 资源副本并在下次请求时直接使用该副本的技术。

Web 缓存可以分为这几种：浏览器缓存、CDN 缓存、服务器缓存、数据库缓存。因为可能会直接使用副本免于重新发送请求或者仅仅确认资源没变无需重新传输资源实体，Web 缓存可以减少延迟加快网页打开速度、重复利用资源减少网络带宽消耗、降低请求次数或者减少传输内容从而减轻服务器压力。

这里主要阐述浏览器 http 缓存，浏览器 http 缓存可以分为强制缓存和协商缓存。强制缓存和协商缓存最大也是最根本的区别在于：强制缓存命中的话不会发请求到服务器，协商缓存一定会发请求到服务器。通过资源的请求首部字段验证资源是否命中协商缓存，如果协商缓存命中，服务器会将这个请求返还，但是不会返回这个资源的实体，而是通知客户端可以从缓存中加载这个资源。

#### Https

Https 就是在 http 上新增了一个 SSL/TLS，它提供了三个基本服务：

1. 加密
2. 身份验证（数字证书）
3. 消息完整性校验

##### 加密

加密的过程可以分为三步：

1. 客户端发起 https 请求，服务端生成公钥和私钥，并把公钥返回给客户端
2. 客户端验证公钥的合法性，验证通过之后用公钥加密密钥，并把经过公钥加密后的密钥传输给服务端
3. 服务端通过私钥解密得到密钥，这个密钥是用于客户端和服务端进行加密通信的对称加密的密钥了

但是服务端的公钥如何被坏人替换了不就全完了？为了防止中间人攻击，所以就有了身份校验。

##### 身份校验

为了保证服务端给客户端下发的公钥是真正的公钥，而不是中间人伪造的公钥，就需要引入数字证书。数字证书是服务端主动去权威机构申请的，证书中包含了由 CA 加密过的服务端的公钥，所以服务端现在只需要向客户端下发数字证书即可。

数字证书中的服务端的公钥是如何加密的呢？是通过非对称加密，只不过这里采用的是权威机构自己的私钥加密的。既然服务端的公钥被权威机构的私钥加密了，那客户端只能通过拿到权威机构的公钥才能解密呀，那这个权威机构的公钥如何安全的传输给客户端呢？这不就陷入了死循环了嘛？

其实权威机构的公钥不需要传输，因为权威机构会和主流的浏览器或操作系统合作，将它们的公钥内置在浏览器或操作系统中。客户端收到证书之后，只需要从证书中找到权威机构的信息，并从本地环境中找到权威机构的公钥，就能正确解密拿到服务端返回的公钥了。

但是如何整个证书都被中间人替换了，或者证书内容被替换了呢？

这些数字证书本身就已经提供了方案，数字证书中除了包含加密之后的服务端公钥，权威机构的信息之外，还包含了证书内容的数字签名（先通过 hash 函数计算得到证书数字摘要，然后用权威机构的私钥加密数字摘要得到数字签名），签名计算方法以及证书对应的域名。这样一来，客户端收到证书之后：

- 使用权威机构的公钥解密数字证书，得到服务端的公钥以及证书的数字签名，然后根据证书上的描述的计算证书签名的方法计算一下当前证书的签名，与收到的签名做对比，如果一样，表示证书一定是服务器下发的，没有被中间人篡改过。中间人虽然有权威机构的公钥，能够解析证书并篡改，但是篡改完成之后中间人需要将证书重新加密，但是中间人没有权威机构的私钥，无法加密。强行加密只会导致客户端无法解密。

##### Https 握手过程

1. 客户端发送 random1 + 支持的加密算法 + SSL 版本信息
2. 服务端发送 random2 + 选择的加密算法 + 证书
3. 客户端验证证书，并用公钥加密的 random3
4. 服务端解密 random3，此时两端共有 random1、random2、random3，使用这 3 个随机数通过加密算法计算对称加密秘钥即可

以上只有 random3 是加密的，所以用 random1+2+3 这三个随机数加密生成密钥。

#### 常见问题汇总

1. 数字证书的作用？

   避免公钥被替换。

2. 数字签名的作用？

   校验公钥的合法性。

3. 握手过程为什么要用到 3 个随机数？

   Https 握手过程中出现的 3 个随机数，只有第三个是加密的随机数。由于很多主机可能产生弱随机数，因此三个随机数叠加更接近随机，比较安全。

#### 参考

[海绵宝宝也懂的HTTPS](https://juejin.im/post/5c341549e51d45524860cf99)

[https://www.jianshu.com/p/ca7df01a9041](https://www.jianshu.com/p/ca7df01a9041)

[浏览器HTTP缓存机制](https://juejin.im/post/5a673af06fb9a01c927ed880)