---
# System prepended metadata

title: HTTP
tags: [knowledge, http, security]

---

# HTTP
###### tags: `http` `security`
### 介紹
HTTP 全名是 「超文本傳輸協定（HyperText Transfer Protocol）」，內容規範了客戶端（client）請求與伺服器（server）回應的標準。

但是這個資料傳輸過程當中，資料都是明文，也就是說如果傳遞的過程中有出現駭客攔截資料，那資料就會洩漏甚至並被盜用。



![](https://i.imgur.com/k05AQXk.png)





因此，為了保護資料傳輸過程當中不會被攔截、竊取，通常會將資料作加密。

### HTTP Request

HTTP Request（請求）由客戶端發起，送到伺服器去，一個請求可能看起來像下面的樣子：

```
POST /login HTTP/1.1
Host: aaronlife.com
Accept: application/json
Content-Type: application/json
Content-Length: 81

{
  "UserId": "Aaron Ho,
  "Password": "AE09-C488-9DFE-0321",
  "Type": 1,
}
```

其結構分成三個部分：

##### 起始行（Start Line）

```
POST https://www.aaronlife.com/login HTTP/1.1
```

1. POST：要使用的HTTP請求方法（Method），HTTP方法有下面幾種：

   | 方法名稱   | 說明                                    |
   | ---------- | --------------------------------------- |
   | **GET**    | 取得資料                                |
   | **POST**   | 提交資料、更新資料                      |
   | **PUT**    | 新增資料                                |
   | **DELETE** | 刪除資料                                |
   | HEAD       | 與GET相同，但回應不會有資料本體（Body） |
   | CONNECT    | 讓指定的資源跟伺服器連線                |
   | OPTIONS    | 指定資源的溝通方式                      |
   | TRACE      | 指定資源跟伺服器之間的來回測試          |
   | PATCH      | 修改部分資料                            |
   
   > **補充**
   >
   > 粗體字為較常用的四個方法，該四個方法長統稱為ＣＲＵＤ（Create、Read、Update、Delete - 增、刪、讀、改）。

2. `https://www.aaronlife.com/login`：方法後面接的是URL，要發出的請求的對象，通常為伺服器的位址。
3. `HTTP/1.1`該請求使用的HTTP版本。

##### 表頭（Headers）

```
Host: aaronlife.com
Accept: application/json
Content-Type: application/json
Content-Length: 81
```

表頭用來存放跟請求相關的一些設定，例如：請求的資料本體類型、認證資料、請求的資料長度等等；每一筆表頭設定都是以：「欄位名稱」跟「欄位值」的型態來表示，例如：`Content-Type`為欄位名稱，而`application/json`為欄位值。

##### 資料本體（Body）

```
{
  "UserId": "Aaron Ho,
  "Password": "AE09-C488-9DFE-0321",
  "Type": 1,
}
```

資料本體則是該次請求要發送給對方的資料，可能是JSON、XML、檔案、純文字等等資料。

### HTTP Response

伺服器端收到請求後會發出HTTP Response（回應），一個HTTP Response看起來像下面的樣子：

```
HTTP/1.1 200 OK
Date: Thu, 24 Dec 2021 04:55:38 GMT
Content-Type: application/json
Content-Length: 19
Connection: keep-alive
CF-Cache-Status: DYNAMIC

{"status":"ok"}
```

##### 狀態列（Status Line）

```
HTTP/1.1 200 OK
```

1. `HTTP/1.1`：伺服器端回應格式使用的HTTP版本。

2. `200`：回應的狀態碼，2xx為成功，3xx為重新導向、4xx為客戶端錯誤、5xx為伺服器錯誤。

   > **補充**
   >
   > 詳細狀態碼可參考：https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Status

3. `OK`：回應的狀態描述。

##### 表頭（Headers）

```
Date: Thu, 24 Dec 2021 04:55:38 GMT
Content-Type: application/json
Content-Length: 19
Connection: keep-alive
CF-Cache-Status: DYNAMIC
```

回應的表頭與請求的表頭格式一樣都是「欄位名稱」與「欄位值」的組合，裡面可能有回應時間、回應資料內容格式等等設定。

##### 資料本體（Body）

```
{"status":"ok"}
```

該次回應的內容，與請求一樣，可能是JSON、XML、檔案、純文字等等資料，可以根據表頭的`Content-Type`欄位得知內資料本體是什麼樣的資料格式。







## 加密

加密指的是把明文（可以讀取的內容）資料轉換成密文（也就是無法讀取的內容），並且密文能藉由特定的解密過程，將無法讀取的內容回復成原來的可以讀取的明文。

> 加密和雜湊不同，雜湊過的內容是無法恢復成原來的樣子的。


### 共用金鑰加密
又稱為對稱式加密，加密的時候必須透過一個特定的金鑰（也可稱為一組密碼）來加密資料，解密的時候必須使用相同的金鑰來還原資料。這個用來加密及解密的方式，就稱為「共用金鑰加密」或「對稱式加密」。

> AES就是一種對稱式加密的方式。



經過共用金鑰加密，資料本身已經無法被沒有金鑰對象讀取，但是如果用於網路傳輸，加密及解密的雙方都必須要知道該金鑰，所以在傳輸加密後的資料之前，必須雙方先交換金鑰，而這個金鑰未經過加密，還是有被攔截的可能，如果金鑰被攔截了，後面的資料即使經過加密，也都可能被使用金要來做解密了。

因此，如果要有安全的資料傳輸，需要其他加密方式。



### 公開金鑰加密

又稱為「非對稱式加密」；在這個加密的方式當中，資料傳輸的方會有成對的兩個金鑰：一個稱為「公鑰」，一個稱為「私鑰」，顧名思義，這個公鑰是可以公開給所有人都看得到，而私鑰是則保留在資料提供者自己的手上，不需要提供給解密方；每個資料被任意一個金鑰（公鑰或私鑰）加密後，必須要透過與之配對的另一個金鑰才能解密；例如用私鑰加密的資料，就只能被我的公鑰解密，被公鑰加密的資料，只能使用私鑰來解密。

在這樣的規則下，進行資料傳輸，即使公鑰被攔截了，攔截方也無法解密資料，因為經過公鑰加密的資料必須透過私鑰來解密。

但很可惜的，即使是這樣，網路上的資料傳輸，還是無法非常安全，因為雖然公鑰對方可以看到並用來解密，但因為公鑰無法證明是不是資料提供方所有，所以當駭客在中間攔截了公鑰後，將公鑰換成另一個，那接收方如果使用了駭客的公鑰加密資料來做回應，駭客就可以輕易取得該回應資料了，這個手段又稱為「中間人攻擊」。

因此，我們需要一個能證明公鑰屬於誰的方法。



### 數位憑證

因此就出現了 「憑證頒發機構」，當資料通訊的雙方要開始進行資料傳輸之前資料提供者必須提供「公鑰」跟「email」，向憑證頒發機構申請憑證，憑證頒發機構核可後，便會透過「數位簽章」來打包資料提供者的資訊，並製作成「數位憑證」。

當通訊開始時，資料提供者會先傳遞數位憑證接收方，接收方便可以透過數位簽章，來證明憑證的內容確實是屬於資料提供者的；這樣，就可以證明公鑰是不是屬於對方的，即使駭客想從中調包公鑰，但因為憑證頒發機構的數位簽章，其通訊過程駭客無法介入，因此就可以證明公鑰的所屬者。



## HTTPS

HTTPS 全名 「超文本傳輸安全協定」，HTTP後面多出來的S是 Secure的意思；HTTPS 透過 HTTP 進行通訊，但傳輸的資料都會使用使用 「SSL/TLS」進行加密，以就是類似於前面介紹的的加密方式，在 HTTP之上定義了較安全的資料傳輸方式。

由於非對稱加密的運算量較高，效率較慢，所以在實際的應用上，會透過公開金鑰加密傳送共用金鑰，再透過共用金鑰加來進行進行之後的資料傳輸工作，這樣就可以兼顧了安全性及資料傳輸效率。



## 瀏覽器的支援

在Google Chrome瀏覽器列上，如果是經過加密的連線，網址左邊會出現一個鎖頭的圖案，代表是經過憑證加密的連線，也就是https連線。

![](https://i.imgur.com/EzqjS0u.png)




但如果網址左邊會出現三角形驚嘆號圖案，並出現「不安全」的訊息，則代連線沒有經過加密，也就是http連線。
![](https://i.imgur.com/Mto929S.png)




>如果你今天連線的網頁資料比較敏感，例如銀行刷卡服務、轉帳等等，需注意連線有沒有經過加密，否則就不要繼續操作，避免資料被攔截。