> For the complete documentation index, see [llms.txt](https://bohans.gitbook.io/ji-chu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bohans.gitbook.io/ji-chu/network/http/https.md).

# HTTPS

**HTTPS 用于解决 HTTP 不安全的缺陷，在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议，使得报文能够加密传输。**

## 混合加密

HTTPS 采用**对称加密**和**非对称加密**结合的「混合加密」方式：

* 在通信建立前采用**非对称加密**的方式交换 「会话秘钥」。
* 在通信过程中全部使用**对称加密**加密明文数据。

采用 「混合加密」 的方式的原因：

* **对称加密**只使用一个密钥，运算速度快，密钥必须保密，无法做到安全的密钥交换。
* **非对称加密**使用两个密钥：公钥和私钥，公钥可以任意分发而私钥保密，解决了密钥交换问题但速度慢。

## 摘要算法 + 数字签名

为了保证传输的内容不被篡改，需要对内容计算出一个 「指纹」，然后同内容一起传输给对方。

**对方收到后，先是对内容也计算出一个 「指纹」，然后跟发送方发送的 「指纹」 做一个比较，如果 「指纹」 相同，说明内容没有被篡改，否则就可以判断出内容被篡改了。**

> 在计算机里会**用摘要算法（哈希函数）来计算出内容的哈希值**，也就是内容的 「指纹」，这个**哈希值是唯一的，且无法通过哈希值推导出内容**。

通过哈希算法可以确保内容不会被篡改，**但是并不能保证 「内容 + 哈希值」 不会被中间人替换，因为这里缺少对客户端收到的消息是否来源于服务端的证明**。

为了避免这种情况，可以用**非对称加密算法**来进行 「签名」：私钥加密，公钥解密。

因为非对称加密的计算比较耗费性能，所以一般不会用非对称加密来加密实际的传输内容，而是**对内容的哈希值进行加密**。

<figure><img src="https://2360649912-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3c4d4G2SmdXooqcxZXXU%2Fuploads%2F7v68SmbdaAbK0Sotfxdp%2F%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D.png?alt=media&amp;token=9c8ffc80-9799-4095-8ac8-284759cd8f6d" alt=""><figcaption></figcaption></figure>

## 数字证书

CA （数字证书认证机构）签发证书的过程：

1. 首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包，然后对这些信息进行 Hash 计算，得到一个 Hash 值；
2. 然后 CA 会使用自己的私钥将该 Hash 值加密，生成 Certificate Signature，也就是 CA 对证书做了签名；
3. 最后将 Certificate Signature 添加在文件证书上，形成数字证书。

客户端校验服务端的数字证书的过程：

1. 首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1；
2. **通常浏览器和操作系统中集成了 CA 的公钥信息，浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容，得到一个 Hash 值 H2 ；**
3. 最后比较 H1 和 H2，如果值相同，则为可信赖的证书，否则则认为证书不可信。

## HTTPS 是如何建立连接的？ <a href="#https-shi-ru-he-jian-li-lian-jie-de-qi-jian-jiao-hu-le-shen-me" id="https-shi-ru-he-jian-li-lian-jie-de-qi-jian-jiao-hu-le-shen-me"></a>

1. 客户端向服务器索要并验证服务器的公钥。
2. 双方协商生产 「会话秘钥」。
3. 双方采用 「会话秘钥」 进行加密通信。

前两步就是 SSL/TLS 的建立过程，也就是 TLS 握手阶段。

具体而言，HTTPS 建立连接需要进行四次通信：

### 1. ClientHello

首先，由客户端向服务器发起加密通信请求，也就是 ClientHello 请求。

在这一步，客户端主要向服务器发送以下信息：

* 客户端支持的 TLS 协议版本，如 TLS 1.2 版本。
* **客户端生产的随机数（Client Random），后面用于生成 「会话秘钥」 条件之一**。
* 客户端支持的密码套件列表，如 RSA 加密算法。

### 2. SeverHello

服务器收到客户端请求后，向客户端发出响应，也就是 SeverHello。

服务器回应的内容有如下内容：

* 确认 TLS 协议版本，如果浏览器不支持，则关闭加密通信。
* **服务器生产的随机数（Server Random），也是后面用于生产 「会话秘钥」 条件之一**。
* 确认的密码套件列表，如 RSA 加密算法。
* **服务器的数字证书。**

### 3. 客户端回应

**客户端收到服务器的回应之后，首先通过浏览器或者操作系统中的 CA 公钥，确认服务器的数字证书的真实性。**

如果证书没有问题，客户端会**从数字证书中取出服务器的公钥**，然后使用它加密报文，向服务器发送如下信息：

* **一个随机数（pre-master key）。该随机数会被服务器公钥加密。**
* 加密通信算法改变通知，表示随后的信息都将用 「会话秘钥」 加密通信。
* 客户端握手结束通知，表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要，用来供服务端校验。

> 上面第一项的随机数是整个握手阶段的第三个随机数，会发给服务端。
>
> **在服务器和客户端中有了三个随机数（Client Random、Server Random、pre-master key）后，它们会使用双方协商的加密算法，各自生成本次通信的 「会话秘钥」**。

### 4.  服务器的最后回应

服务器收到客户端的第三个随机数（pre-master key）之后，通过协商的加密算法，计算出本次通信的 「会话秘钥」。

然后，向客户端发送最后的信息：

* 加密通信算法改变通知，表示随后的信息都将用 「会话秘钥」 加密通信。
* 服务器握手结束通知，表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要，用来供客户端校验。

## HTTP 与 HTTPS 有哪些区别？ <a href="#http-yu-https-you-na-xie-qu-bie" id="http-yu-https-you-na-xie-qu-bie"></a>

* HTTP 是超文本传输协议，信息是明文传输，存在安全风险的问题。HTTPS 解决了 HTTP 不安全的缺陷，在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议，使得报文能够加密传输。
* HTTP 连接建立相对简单，TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后，还需进行 SSL/TLS 的握手过程，才可进入加密报文传输。
* 两者的默认端口不一样，HTTP 默认端口号是 80，HTTPS 默认端口号是 443。
* HTTPS 协议需要向 CA（证书权威机构）申请数字证书，来保证服务器的身份是可信的。
