Learning Objectives
- 讀懂 HTTP 請求與回應的格式:方法、路徑、標頭、空行、內容,以及狀態碼的五類
- 說明 HTTP 是明文,同一個網路上的人看得到請求的全部內容
- 說明 HTTPS 就是 HTTP 加上 TLS,以及 TLS 提供的機密性、完整性與身分驗證
- 依序說出 TLS 1.3 交握的訊息,以及每一步完成了什麼
- 說明憑證鏈怎麼一路對到信任的根憑證,並判斷瀏覽器憑證錯誤代表的意思
從查到位址到看到網頁
上一課,DNS 把 www.club.tw 換成了 IP 位址。接下來瀏覽器和那台伺服器建立 TCP 連線,用 HTTP(HyperText Transfer Protocol)要網頁。
計算機概論軌第 32 課〈全球資訊網與 HTTP〉介紹過網址與請求的概念;這一課看 HTTP 訊息實際長什麼樣子,以及 HTTPS 怎麼保護它。
HTTP/1.1 的訊息是純文字,一行一行寫,每行以 \r\n(CR LF)結尾。一個請求長這樣:
GET /events?month=11 HTTP/1.1 ← 請求列:方法、路徑、版本
Host: www.club.tw ← 標頭:一行一個「名稱: 值」
User-Agent: Mozilla/5.0
Accept: text/html
← 空行:標頭到這裡結束
伺服器的回應:
HTTP/1.1 200 OK ← 狀態列:版本、狀態碼、說明
Content-Type: text/html; charset=utf-8
Content-Length: 1532
← 空行
<!doctype html><html>… ← 內容(body),長度由 Content-Length 說明
HTTP 的意義(方法、狀態碼、標頭)定義在 RFC 9110,HTTP/1.1 的訊息格式定義在 RFC 9112(兩份都在 2022 年發布)。
方法與狀態碼
常見的方法(method):
| 方法 | 用途 | 例子 |
|---|---|---|
| GET | 取得資源 | 打開網頁、下載圖片 |
| POST | 送出資料讓伺服器處理 | 登入、送出表單 |
| PUT | 用送上去的內容取代資源 | 更新一筆資料 |
| DELETE | 刪除資源 | 刪除一篇貼文 |
| HEAD | 跟 GET 一樣,但只要標頭 | 檢查檔案有沒有更新 |
狀態碼(status code)是三位數,第一位數字代表類別:
| 類別 | 意思 | 常見的例子 |
|---|---|---|
| 1xx | 資訊:收到了,繼續處理 | 101 Switching Protocols |
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 重新導向:要再做一個動作 | 301 Moved Permanently、302 Found、304 Not Modified |
| 4xx | 用戶端錯誤:請求有問題 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found |
| 5xx | 伺服器錯誤:請求沒問題,伺服器處理失敗 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable |
排錯時先看第一位數字:4xx 要檢查自己送出的請求(網址、權限、登入),5xx 是伺服器那一端的問題。
HTTPS:在 HTTP 底下加一層 TLS
HTTP 的問題是明文:咖啡店的 Wi-Fi 上,只要有人擷取封包,就看得到你送出的網址、Cookie、帳號與密碼,還可能在路上改掉回應的內容。
HTTPS 就是「HTTP over TLS」:HTTP 的訊息完全一樣,只是先交給 TLS(Transport Layer Security)加密,再交給 TCP;預設的連接埠從 80 變成 443。
| 層 | HTTP | HTTPS |
|---|---|---|
| 應用層 | HTTP | HTTP |
| 安全層 | (沒有) | TLS |
| 傳輸層 | TCP,80 埠 | TCP,443 埠 |
TLS 提供三件事:
| 保護 | 意思 | 靠什麼 |
|---|---|---|
| 機密性 | 路上的人看不到內容 | 雙方交握時算出的共同金鑰,用對稱式加密 |
| 完整性 | 內容被改過一定會被發現 | 每筆資料附上驗證標籤(AEAD) |
| 身分驗證 | 確認對方真的是 www.club.tw,不是冒充的 | 伺服器的憑證,以及它用私鑰做的簽章 |
TLS 1.3 的規格最早是 RFC 8446(2018 年);2026 年發布的修訂版 RFC 9846 取代了它,協定版本仍然是 TLS 1.3。
TLS 1.3 交握的步驟
TCP 連線建立之後,TLS 1.3 用一次往返完成交握:
| 順序 | 訊息 | 方向 | 加密嗎 | 完成什麼 |
|---|---|---|---|---|
| 1 | ClientHello | 用戶端 → 伺服器 | 否 | 提出支援的 TLS 版本與密碼套件、要連的名稱(SNI),附上自己的金鑰交換公開值 |
| 2 | ServerHello | 伺服器 → 用戶端 | 否 | 選定密碼套件,附上自己的公開值;雙方從此算得出同一把金鑰 |
| 3 | EncryptedExtensions | 伺服器 → 用戶端 | 是 | 其他設定(例如之後用 HTTP/1.1 還是 HTTP/2) |
| 4 | Certificate | 伺服器 → 用戶端 | 是 | 伺服器的憑證鏈 |
| 5 | CertificateVerify | 伺服器 → 用戶端 | 是 | 用私鑰對交握內容簽章,證明自己擁有這張憑證 |
| 6 | Finished | 伺服器 → 用戶端 | 是 | 對整段交握算出驗證值,確認沒有被竄改 |
| 7 | Finished | 用戶端 → 伺服器 | 是 | 用戶端的驗證值;接著就可以送加密的 HTTP 請求 |
關鍵在第 1、2 步的金鑰交換:雙方各自產生一個秘密值,只把由它算出的「公開值」送給對方。 路上的人看得到兩個公開值,卻算不出雙方共同的金鑰;雙方則各用「自己的秘密值+對方的公開值」算出同一把金鑰。
所以 HTTPS 比 HTTP 多花一次往返:TCP 交握一次、TLS 交握一次,第三次才拿到回應。 連到國外、往返時間 200 毫秒的伺服器,多出來的這一次就是 200 毫秒,這是瀏覽器盡量重複使用同一條連線的原因之一。
小測驗:HTTP 與 HTTPS
伺服器回應 HTTP/1.1 404 Not Found。問題比較可能出在哪裡?
HTTP/1.1 請求的標頭和內容之間用什麼分開?
下面哪一個狀態碼代表「伺服器端出了問題」?
TLS 1.3 交握時,伺服器的憑證是怎麼送給用戶端的?
憑證與憑證鏈
加密只能防止別人偷看;如果你一開始就連到冒充的伺服器,加密也沒有用。憑證(certificate)用來確認對方的身分。
一張網站憑證(格式是 X.509,網際網路上的用法定義在 RFC 5280)主要寫著:
| 欄位 | 內容 |
|---|---|
| 名稱(SAN) | 這張憑證可以用在哪些網域,例如 www.club.tw、club.tw,或萬用字元 *.club.tw |
| 有效期間 | 從哪一天到哪一天 |
| 公開金鑰 | 伺服器的公開金鑰;對應的私鑰只有伺服器有 |
| 簽發者 | 哪個憑證機構(CA,Certificate Authority)簽發的,以及 CA 的數位簽章 |
瀏覽器怎麼相信這張憑證?靠一條憑證鏈:
網站憑證 www.club.tw ← 由中繼 CA 簽發,伺服器送出
↑ 簽發
中繼憑證 Demo Issuing CA 1 ← 由根 CA 簽發,伺服器一起送出
↑ 簽發
根憑證 Demo Root CA ← 內建在作業系統或瀏覽器裡(信任的根憑證清單)
瀏覽器從網站憑證開始,一張一張檢查「簽發者的簽章對不對」,直到碰到自己信任的根憑證。同時檢查每一張都在有效期間內,以及網站憑證的名稱符合網址。 根 CA 的私鑰平常不直接拿來簽網站憑證,而是交給中繼 CA 簽,所以伺服器必須把中繼憑證一起送出。
萬用字元的規則:*.club.tw 只代表最左邊的一段,所以 www.club.tw、shop.club.tw 符合,club.tw 本身和 a.b.club.tw 都不符合。
瀏覽器的憑證警告代表什麼
憑證驗證失敗時,瀏覽器會擋下連線並顯示警告(各瀏覽器的字句不同)。常見的原因:
| 警告的原因 | 可能的情況 | 該怎麼做 |
|---|---|---|
| 憑證已過期 | 網站忘了更新憑證;或你電腦的日期設錯 | 先檢查自己電腦的日期;網站的話通知管理者 |
| 名稱不符 | 網址打錯、網站設定錯誤,或有人冒充這個網站 | 確認網址;不要繼續輸入密碼 |
| 簽發者不受信任 | 自簽憑證(常見於家用設備、測試機),或攻擊者偽造的憑證 | 公共網路上不要按「繼續前往」 |
| 憑證鏈不完整 | 伺服器少送了中繼憑證 | 這是伺服器的設定問題,由管理者修正 |
兩個常見的誤會:
- 鎖頭圖示不代表網站可信。它只代表「連線有加密,而且對方擁有這個名稱的有效憑證」。詐騙網站一樣可以替自己的網域申請到憑證,所以還是要看清楚網域名稱。
- 在警告頁按「繼續前往」等於放棄身分驗證。如果真的有人在中間冒充伺服器,你的密碼就會直接交給他。
小測驗:憑證
憑證的名稱只有 *.club.tw。用它連下面哪一個網址會出現名稱不符的警告?
為什麼伺服器要把中繼憑證一起送給瀏覽器?
一個網址列有鎖頭圖示的網站,下面哪一個說法正確?
重點整理
- HTTP 訊息是文字:請求列(方法、路徑、版本)或狀態列(版本、狀態碼),接著標頭,一個空行,再來是內容。
- 狀態碼看第一位:1xx 資訊、2xx 成功、3xx 重新導向、4xx 用戶端錯誤、5xx 伺服器錯誤。
- HTTP 是明文;HTTPS=HTTP+TLS,預設 443 埠,提供機密性、完整性與身分驗證。
- TLS 1.3 交握:ClientHello、ServerHello 交換公開值算出金鑰,接著加密送出憑證、CertificateVerify、Finished;比 HTTP 多一次往返。
- 瀏覽器沿著憑證鏈驗證到信任的根憑證,並檢查名稱與有效期間;任何一項失敗就會出現警告。鎖頭不代表網站可信。
下一課換一個角度:用封包分析工具,把這兩課看到的 DNS、TCP、HTTP 封包一個一個拆開來讀。