# HTTPS 流程

<figure><img src="/files/MD56ajWa19AsUx86GChP" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/SuNcAJZ1keYfrYiVFGts" alt=""><figcaption><p><a href="https://blog.bytebytego.com/p/how-does-https-work-episode-6">https://blog.bytebytego.com/p/how-does-https-work-episode-6</a></p></figcaption></figure>

可參考原始碼：<https://github.com/chromium/chromium/blob/main/net/socket/ssl_client_socket_impl.cc#L474>

接著看 Wireshark 實際發送封包之流程

<figure><img src="/files/if9RmJjkuJWAoKkW8rb8" alt=""><figcaption></figcaption></figure>

HTTPS 的交握步驟詳細如下：

* **ClientHello**：
  * 客戶端生成一個隨機數 `random-client`，並將其連同支持的TLS版本、密碼套件（cipher suites）、壓縮方法和可選擴展等信息發送到服務器端。
  * 傳遞內容：
    * **支持的TLS版本**：表示客戶端支持的TLS協議版本（例如TLS 1.2或TLS 1.3）。
    * **密碼套件**：包括客戶端支持的加密算法、鑰匙交換算法、MAC算法等的列表。
    * **擴展**：例如SNI（Server Name Indication）擴展，用於支持多域名的HTTPS。
* **ServerHello**：
  * 服務器生成一個隨機數 `random-server`，並選擇TLS版本、密碼套件，並將其連同服務器的公鑰證書一併回傳給客戶端。
  * 傳遞內容：
    * **公鑰證書**：服務器的數字證書，包含服務器的公鑰和由可信任的證書頒發機構（CA）簽名的證書。
    * **密碼套件選擇**：服務器從客戶端提供的列表中選擇一個共同支持的密碼套件。
* **客戶端回應**：
  * **描述**：客戶端收到服務器的`ServerHello`消息後，保存`random-server`和公鑰，然後生成一個`premaster secret`，並用服務器的公鑰加密後發送給服務器。
  * **技術細節**：
    * **premaster secret**：一個隨機生成的值，用於生成會話密鑰。此值僅在這次會話中使用。
    * **加密**：使用服務器的公鑰加密`premaster secret`，保證傳輸過程中的安全。
* **服務器解密**：
  * **描述**：服務器使用其私鑰解密客戶端傳來的`premaster secret`，此時雙方都擁有了`random-client`、`random-server`和`premaster secret`這三個關鍵要素。
  * **技術細節**：
    * **私鑰解密**：服務器使用其私鑰解密`premaster secret`，保證只有服務器能夠獲取此值。
    * **會話密鑰生成**：雙方使用`random-client`、`random-server`和`premaster secret`通過協商好的算法生成會話密鑰（`session keys`）。
* **建立安全通道**：

  * **描述**：安全通道建立後，雙方開始使用會話密鑰加密通信內容，保證傳輸的機密性和完整性。
  * **技術細節**：

    * **Change Cipher Spec**：通知對方接下來的通信將使用新協商的密碼套件。

    * **Finished**：雙方交換加密的`Finished`消息，確認握手過程無誤並開始安全通信。

  > `session key`: 是 TLS/SSL 最後協商得出的共同密鑰，用来進行後續所有封包的對稱式加密。

可將以下檔案導入 Wireshark 查看

{% file src="/files/BhedIKgEYSX7NLwwCUCh" %}

***

***

## **PKI 系統（Public Key Infrastructure）**

公鑰基礎設施（PKI）是一套管理數字證書和公私鑰對的技術和規範。PKI 系統的主要組成部分和功能如下：

1. **證書頒發機構（CA, Certificate Authority）**：
   * CA 是一個受信任的實體，負責頒發和管理數字證書。它驗證申請者的身份並簽署數字證書，確保證書的真實性和有效性。
2. **註冊機構（RA, Registration Authority）**：
   * RA 是 CA 的代理，負責接收證書申請，驗證申請者的身份，並將已驗證的申請轉發給 CA。
3. **數字證書**：
   * 數字證書包含持有者的公鑰、持有者的身份信息、CA 的簽名和其他相關信息。證書用來驗證持有者的身份並確保通信的安全性。
   * 常見的證書格式是 X.509。
4. **密鑰生成和管理**：
   * PKI 系統負責生成、分發、存儲和管理密鑰對。密鑰管理包括密鑰的備份、恢復、更新和撤銷。

以 AWS 為例，類似以下流程：

```
  User (You)        AWS (RA)                CA (Amazon Trust Services)
     |                  |                               |
     |  Request Cert    |                               |
     |----------------->|                               |
     |                  |   Validate Domain (DNS/Email) |
     |                  |------------------------------>|
     |                  |                               |
     |                  |  Issue Cert                   |
     |                  |<------------------------------|
     |                  |                               |
     |   Use Cert       |                               |
     |<-----------------|                               |
     |                  |                               |

```

電腦預設會裝有 CA 憑證

<figure><img src="/files/plzmoMTmEbZwssQQt0H3" alt=""><figcaption></figcaption></figure>

### **自己當 CA 並幫其他網站簽發 HTTPS 證書之技術步驟**

#### 1. 生成自己的 CA 的密鑰對

```sh
sh複製程式碼# 生成一個 2048 位的 RSA 私鑰，用於 CA
openssl genpkey -algorithm RSA -out ca_private_key.pem -pkeyopt rsa_keygen_bits:2048

# 從私鑰中提取公鑰，生成 CA 的公鑰證書
openssl req -new -x509 -key ca_private_key.pem -out ca_cert.pem -days 3650 -subj "/CN=My CA"
```

這會生成一個 CA 的私鑰 `ca_private_key.pem` 和一個自簽名的 CA 公鑰證書 `ca_cert.pem`。

#### 2. 幫其他伺服器生成密鑰對

```sh
# 生成一個 2048 位的 RSA 私鑰，用於伺服器
openssl genpkey -algorithm RSA -out server_private_key.pem -pkeyopt rsa_keygen_bits:2048

# 從私鑰中提取公鑰
openssl rsa -pubout -in server_private_key.pem -out server_public_key.pem
```

#### 3. 創建為了簽發其他 HTTPS 伺服器證書的 CSR（Certificate Signing Request）

CSR 包含伺服器的公鑰和身份信息，並用私鑰簽名。

```sh
openssl req -new -key server_private_key.pem -out server.csr -subj "/CN=www.example.com"
```

#### 4. 使用 CA 簽署伺服器的 CSR

CA 驗證伺服器的身份後，簽署 CSR 並生成數字證書。

```sh
openssl x509 -req -in server.csr -CA ca_cert.pem -CAkey ca_private_key.pem -CAcreateserial -out server_cert.pem -days 365
```

即會生成伺服器的數字證書 `server_cert.pem`。

#### 5. 配置伺服器

將數字證書 `server_cert.pem` 和私鑰 `server_private_key.pem` 配置到伺服器，準備進行 SSL/TLS 。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://easonwang.gitbook.io/web_advance/https/https-liu-cheng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
