TLS/SSL

**傳輸層安全性協定**（英語：**T**ransport **L**ayer **S**ecurity，縮寫：**TLS**）前身稱為**安全通訊協定**（英語：**S**ecure **S**ockets **L**ayer，縮寫：**SSL**）是一種安全協定，目的是為網際網路通訊提供安全及資料完整性保障。

網景公司（Netscape）在 1994 年推出首版網頁瀏覽器－網景領航員時，推出 HTTPS 協定，以 SSL 進行加密，這是 SSL 的起源。

IETF 將 SSL 進行標準化，1999 年公布 TLS 1.0 標準檔案（RFC 2246）。隨後又公布 TLS 1.1（RFC 4346，2006 年）、TLS 1.2（RFC 5246，2008 年）和 TLS 1.3（RFC 8446，2018 年）。在瀏覽器、電子郵件、即時通訊、VoIP、網路傳真等應用程式中，廣泛使用這個協定。許多網站，如 Google、Facebook、Wikipedia 等也以這個協定來建立安全連線，傳送資料。目前已成為網際網路上保密通訊的工業標準。

SSL 包含記錄層（Record Layer）和傳輸層，記錄層協定確定傳輸層資料的封裝格式。傳輸層安全協定使用 X.509 認證，之後利用非對稱加密演算來對通訊方做身分認證，之後交換對稱密匙作為會話密匙（Session key）。這個會談密匙是用來將通訊兩方交換的資料做加密，保證兩個應用間通訊的保密性和可靠性，使客戶與伺服器應用之間的通訊不被攻擊者竊聽。

## 概論

TLS 協定採用主從式架構模型，用於在兩個應用程式間透過網路建立起安全的連線，防止在交換資料時受到竊聽及篡改。

TLS 協定的優勢是與高層的應用層協定（如 HTTP、FTP、Telnet 等）無耦合。應用層協定能透明地執行在 TLS 協定之上，由 TLS 協定進行建立加密通道需要的協商和認證。應用層協定傳送的資料在通過 TLS 協定時都會被加密，從而保證通訊的私密性。

TLS 協定是可選的，必須組態客戶端和伺服器才能使用。主要有兩種方式實現這一目標：一個是使用統一的 TLS 協定通訊埠（例如：用於 HTTPS 的埠 443）；另一個是客戶端請求伺服器連接到 TLS 時使用特定的協定機制（例如：電子郵件常用的 STARTTLS）。一旦客戶端和伺服器都同意使用 TLS 協定，他們通過使用一個交握過程協商出一個有狀態的連接以傳輸資料。通過交握，客戶端和伺服器協商各種參數用於建立安全連接：

* 當客戶端連接到支援 TLS 協定的伺服器要求建立安全連接並列出了受支援的密碼套件（包括加密演算法、雜湊演算法等），交握開始。
* 伺服器從該列表中決定密碼套件，並通知客戶端。
* 伺服器發回其數位憑證，此憑證通常包含伺服器的名稱、受信任的憑證頒發機構（CA）和伺服器的公鑰。
* 客戶端確認其頒發的憑證的有效性。
* 為了生成對談金鑰用於安全連接，客戶端使用伺服器的公鑰加密隨機生成的金鑰，並將其傳送到伺服器，只有伺服器才能使用自己的私鑰解密。
* 利用亂數，雙方生成用於加密和解密的對稱金鑰。這就是 TLS 協定的交握，交握完畢後的連接是安全的，直到連接（被）關閉。如果上述任何一個步驟失敗，TLS 交握過程就會失敗，並且斷開所有的連接。

## 發展歷史

### 安全網路編程

早期的研究工作，為方便改造原有網路應用程式，在 1993 年已經有了相似的 Berkeley 通訊端安全傳輸層 API 方法。

### SSL 1.0、2.0 和 3.0

SSL（Secure Sockets Layer）是網景公司（Netscape）設計的主要用於 Web 的安全傳輸協定，這種協定在 Web 上獲得了廣泛的應用。

基礎演算法由作為網景公司的首席科學家塔希爾・蓋莫爾（Taher Elgamal）編寫，所以他被人稱為「SSL 之父」。

2014 年 10 月，Google 發布在 SSL 3.0 中發現設計缺陷，建議禁用此一協定。攻擊者可以向 TLS 發送虛假錯誤提示，然後將安全連接強行降級到過時且不安全的 SSL 3.0，然後就可以利用其中的設計漏洞竊取敏感資訊。Google 在自己公司相關產品中陸續禁止回溯相容，強制使用 TLS 協定。Mozilla 也在 11 月 25 日發布的 Firefox 34 中徹底禁用了 SSL 3.0。微軟同樣發出了安全通告。

* 1.0 版本從未公開過，因為存在嚴重的安全漏洞。
* 2.0 版本在 1995 年 2 月發布。2011 年，RFC 6176 標準棄用了 SSL 2.0。
* 3.0 版本在 1996 年發布，是由網景工程師保羅・科切、Phil Karlton 和 Alan Freier 完全重新設計的。2015 年，RFC 7568 標準棄用了 SSL 3.0。

### TLS 1.0

IETF 將 SSL 標準化，即 RFC 2246 ，並將其稱為 TLS（Transport Layer Security）。

### TLS 1.1

TLS 1.1 在 RFC 4346 中定義，於 2006 年 4 月發表，它是 TLS 1.0 的更新。在此版本中的差異包括：

* 加入對 CBC 攻擊的保護：
  * 隱式 IV 被替換成一個顯式的 IV。
  * 更改區塊加密法模式中的填充錯誤。
* 支援 IANA 登記的參數。

微軟、Google、蘋果、Mozilla 四家瀏覽器業者將在 2020 年終止支援 TLS 1.0 及 1.1 版。2021 年 3 月，RFC 8996 標準棄用了 TLS 1.0 和 TLS 1.1。

### TLS 1.2

TLS 1.2 在 RFC 5246 中定義，於 2008 年 8 月發表。它基於更早的 TLS 1.1 規範。主要區別包括：

* 增加 SHA-2 密碼雜湊函式。
* 增加 AEAD 加密演算法，如 GCM 模式。
* 加入 TLS 擴充定義和 AES 密碼組合。所有 TLS 版本在 2011 年 3 月發布的 RFC 6176 中刪除了對 SSL 的相容，這樣 TLS 對談將永遠無法協商使用的 SSL 2.0 以避免安全問題。

### TLS 1.3

TLS 1.3 在 RFC 8446 中定義，於 2018 年 8 月發表。它與 TLS 1.2 的主要區別包括：

* 將密鑰交換演算法（如 ECDHE）和認證演算法（如 RSA）從密碼套件中分離出來。
* 移除 MD5、SHA1 密碼雜湊函式的支援。
* 請求數位簽章。
* 整合 HKDF 和半短暫 DH 提議。
* 替換使用 PSK 和票據的恢復。
* 支援 1-RTT 交握並初步支援 0-RTT。
* 通過在密鑰協商期間使用臨時金鑰來保證完善的前向安全性。
* 放棄許多不安全或過時特性的支援，包括資料壓縮、重新協商、非 AEAD 加密演算法、靜態 RSA 和靜態 DH 金鑰交換、自訂 DHE 分組、點格式協商、更改密碼本規範的協定、UNIX 時間的 Hello 訊息，以及長度欄位 AD 輸入到 AEAD 密碼本。
* 較 TLS 1.2 速度更快，效能更好。
* 移除 RC4 加密演算法的支援。
* 整合對談雜湊的使用。
* 棄用記錄層版本號和凍結數以改進向下相容性。
* 將一些安全相關的演算法細節從附錄移動到標準，並將 ClientKeyShare 降級到附錄。
* 支援 Ed25519 和 Ed448 數位簽章演算法。
* 支援 X25519 密鑰交換。
* 支援帶 Poly1305 訊息驗證碼的 ChaCha20 加密演算法。
* 支援加密伺服器名稱指示（**E**ncrypted **S**erver **N**ame **I**ndication, ESNI）。

網路安全服務（NSS）是由 Mozilla 開發並由其網路瀏覽器 Firefox 使用的加密庫，自 2017 年 2 月起便預設啟用 TLS 1.3。隨後 TLS 1.3 被加入到 2017 年 3 月發布的 Firefox 52.0 中，但它由於某些使用者的相容性問題，預設情況下禁用。直到 Firefox 60.0 才正式預設啟用。

Google Chrome 曾在 2017 年短時間將 TLS 1.3 設為預設，然而由於類似 Blue Coat Systems 等不相容組件而被取消。

wolfSSL 在 2017 年 5 月發布的 3.11.1 版本中啟用了 TLS 1.3。作為第一款支援 TLS 1.3 部署，wolfSSL 3.11.1 支援 TLS 1.3 Draft 18（現已支援到 Draft 28），同時官方也發布了一系列關於 TLS 1.2 和 TLS 1.3 效能差距的部落格。

## 演算法

### 金鑰交換和金鑰協商

在客戶端和伺服器開始交換 TLS 所保護的加密資訊之前，他們必須安全地交換或協定加密金鑰和加密資料時要使用的密碼。用於金鑰交換的方法包括：使用 RSA 演算法生成公鑰和私鑰（在 TLS 交握協定中被稱為 TLS\_RSA）、Diffie-Hellman（在 TLS 交握協定中被稱為 TLS\_DH）、臨時 Diffie-Hellman（在 TLS 交握協定中被稱為 TLS\_DHE）、橢圓曲線迪菲 - 赫爾曼（在 TLS 交握協定中被稱為 TLS\_ECDH）、臨時橢圓曲線 Diffie-Hellman（在 TLS 交握協定中被稱為 TLS\_ECDHE）、匿名 Diffie-Hellman（在 TLS 交握協定中被稱為 TLS\_DH\_anon）和預共享金鑰（在 TLS 交握協定中被稱為 TLS\_PSK）。

TLS\_DH\_anon 和 TLS\_ECDH\_anon 的金鑰協商協定不能驗證伺服器或使用者，因為易受中間人攻擊因此很少使用。只有 TLS\_DHE 和 TLS\_ECDHE 提供前向保密能力。

在交換過程中使用的公鑰 / 私鑰加密金鑰的長度和在交換協定過程中使用的公鑰憑證也各不相同，因而提供的**強健性**的安全。2013 年 7 月，Google 宣布向其使用者提供的 TLS 加密將不再使用 1024 位元公鑰並切換到至少 2048 位元，以提高安全性。

### 加密密碼

**標註**

### 資料完整性

訊息鑑別碼（MAC）用於對資料完整性進行認證。HMAC 用於 CBC 模式的塊密碼。AEAD 例如 GCM 模式和 CCM 模式使用 AEAD 內建的訊息鑒別碼，不使用 HMAC。另外，在 TLS 交握過程中需要使用基於 HMAC 的偽隨機函式（PRF），或 HKDF。

## 過程

TLS 在網際網路上為 HTTP 等應用程式提供身分驗證、加密、完整性，其基礎是公鑰基礎設施。這是因為公鑰基礎設施普遍商業運營。TLS 協定的設計在某種程度上能夠使主從架構應用程式通訊預防竊聽、干擾和訊息偽造。

TLS 包含幾個基本階段：

1. 對等協商支援的 TLS 版本，和支援的密碼套件。
2. 基於非對稱金鑰的身分認證，通常是基於 PKI 憑證的身分認證。伺服器將其 X.509 憑證發送給客戶端，由客戶端驗證伺服器的身分。如果伺服器要驗證客戶端的憑證，則客戶端可能會將客戶端憑證發送給伺服器。通常僅驗證伺服器，不驗證客戶端。
3. 基於對稱金鑰的數據加密。客戶端生成隨機數作為對談金鑰，並使用伺服器公鑰（伺服器公鑰在伺服器憑證中）加密對談金鑰，最後將已加密的對談金鑰發送給伺服器。由伺服器的私鑰解密出對談金鑰。最後使用此對談金鑰加密數據。TLS 也可以使用預共享金鑰（PSK）作為對稱密鑰。

在第一階段，客戶端與伺服器協商所用密碼演算法。當前廣泛實現的演算法選擇如下：

* 身分驗證：RSA、DSA、ECDSA；
* 密鑰交換：PSK、Diffie-Hellman、ECDH；
* 對稱金鑰加密：RC4、DES、3DES、AES、ChaCha20 以及 Camellia；
* 雜湊函式：MD5、SHA 家族。

## 參考文獻

## 外部連結

* SSL/TLS/WTLS 原理（頁面存檔備份，存於網際網路檔案館）
* SSL 組態指南（頁面存檔備份，存於網際網路檔案館）
* SSL 狀態檢查、格式轉換、漏洞掃描工具（頁面存檔備份，存於網際網路檔案館）

## 參見

* 應用層協定協商
* SSL 加速
* 擴充驗證憑證