'HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇'

通信 瀏覽器 PGP 設計 算法 Go語言中文網 2019-07-20
"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • type:
  • 用於處理 TLS 握手層的高級協議。

C

 enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* RFC 6520 */
(255)
} ContentType;

ContentType 是對握手協議的封裝,消息頭類型和握手層子協議編號的對應關係如下:

消息頭類型

ContentTypechange_cipher_spec0x014alert0x015handshake0x016application_data0x017heartbeat (TLS 1.3 新增)0x018

  • legacy_record_version:
  • 對於除初始 ClientHello 之外的 TLS 1.3 實現生成的所有記錄(即,在 HelloRetryRequest 之後未生成的記錄),必須將其設置為 0x0303,其中出於兼容性目的,它也可以是0x0301。該字段在 TLS 1.3 中已經棄用,必須忽略它。在某些情況下,以前版本的 TLS 將在此字段中使用其他值。

在 TLS 1.3 中,version 為 0x0304,過去版本與 version 的對應關係如下:

協議版本versionTLS 1.30x0304TLS 1.20x0303TLS 1.10x0302TLS 1.00x0301SSL 3.00x0300

  • length:
  • TLSPlaintext.fragment 的長度(以字節為單位)。長度不得超過 2 ^ 14 字節。接收超過此長度的記錄的端點必須使用 "record_overflow" alert 消息終止連接。
  • fragment:
  • 正在傳輸的數據。此字段的值是透明的,它並被視為一個獨立的塊,由類型字段指定的更高級別協議處理。

當尚未使用密碼保護時,TLSPlaintext 結構是直接寫入傳輸線路中的。一旦記錄保護開始,TLSPlaintext 記錄將受到密碼保護。請注意,應用數據記錄不得寫入未受保護的連接中。所以在握手成功之前,是不能發送應用數據的。

TLS 記錄層協議在整個 TLS 協議中的定位如下:

  • 封裝處理 TLS 上層(握手層)中的平行子協議(TLS 1.3 中是 5 個子協議,TLS 1.2 及更老的版本是 4 個子協議),加上消息頭,打包往下傳遞給 TCP 處理。
  • 對上層應用數據協議進行密碼保護,對其他的子協議只是簡單封裝(即不加密)

關於 TLS 記錄層協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

2. TLS 密碼切換協議

注意:該協議在 TLS 1.3 標準規範中已經刪除,但是實際使用中為了兼容 TLS 老版本和一些消息中間件,所以實際傳輸中還可能用到這個協議。

change_cipher_spec (以下簡稱 CCS 協議) 協議,是 TLS 記錄層對應用數據是否進行加密的分界線。客戶端或者服務端一旦收到對端發來的 CCS 協議,就表明接下來傳輸數據過程中可以對應用數據協議進行加密了。

TLS 記錄層在處理上層 5 個協議(密碼切換協議,警告協議,握手協議,心跳協議,應用數據協議)的時候,TLS 不同版本對不同協議加密的情況不同,具體情況如下:

協議版本密碼切換協議警告協議握手協議心跳協議應用數據協議TLS 1.3無✅(根據連接狀態不同進行加密,即一部分會加密)✅(一部分加密)❌✅TLS 1.2❌❌❌無✅

關於 TLS CCS 協議更多細節將在接下來的握手文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

協議數據結構如下:

C

 struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;

經過 TLS 記錄層包裝以後,結構如下:


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • type:
  • 用於處理 TLS 握手層的高級協議。

C

 enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* RFC 6520 */
(255)
} ContentType;

ContentType 是對握手協議的封裝,消息頭類型和握手層子協議編號的對應關係如下:

消息頭類型

ContentTypechange_cipher_spec0x014alert0x015handshake0x016application_data0x017heartbeat (TLS 1.3 新增)0x018

  • legacy_record_version:
  • 對於除初始 ClientHello 之外的 TLS 1.3 實現生成的所有記錄(即,在 HelloRetryRequest 之後未生成的記錄),必須將其設置為 0x0303,其中出於兼容性目的,它也可以是0x0301。該字段在 TLS 1.3 中已經棄用,必須忽略它。在某些情況下,以前版本的 TLS 將在此字段中使用其他值。

在 TLS 1.3 中,version 為 0x0304,過去版本與 version 的對應關係如下:

協議版本versionTLS 1.30x0304TLS 1.20x0303TLS 1.10x0302TLS 1.00x0301SSL 3.00x0300

  • length:
  • TLSPlaintext.fragment 的長度(以字節為單位)。長度不得超過 2 ^ 14 字節。接收超過此長度的記錄的端點必須使用 "record_overflow" alert 消息終止連接。
  • fragment:
  • 正在傳輸的數據。此字段的值是透明的,它並被視為一個獨立的塊,由類型字段指定的更高級別協議處理。

當尚未使用密碼保護時,TLSPlaintext 結構是直接寫入傳輸線路中的。一旦記錄保護開始,TLSPlaintext 記錄將受到密碼保護。請注意,應用數據記錄不得寫入未受保護的連接中。所以在握手成功之前,是不能發送應用數據的。

TLS 記錄層協議在整個 TLS 協議中的定位如下:

  • 封裝處理 TLS 上層(握手層)中的平行子協議(TLS 1.3 中是 5 個子協議,TLS 1.2 及更老的版本是 4 個子協議),加上消息頭,打包往下傳遞給 TCP 處理。
  • 對上層應用數據協議進行密碼保護,對其他的子協議只是簡單封裝(即不加密)

關於 TLS 記錄層協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

2. TLS 密碼切換協議

注意:該協議在 TLS 1.3 標準規範中已經刪除,但是實際使用中為了兼容 TLS 老版本和一些消息中間件,所以實際傳輸中還可能用到這個協議。

change_cipher_spec (以下簡稱 CCS 協議) 協議,是 TLS 記錄層對應用數據是否進行加密的分界線。客戶端或者服務端一旦收到對端發來的 CCS 協議,就表明接下來傳輸數據過程中可以對應用數據協議進行加密了。

TLS 記錄層在處理上層 5 個協議(密碼切換協議,警告協議,握手協議,心跳協議,應用數據協議)的時候,TLS 不同版本對不同協議加密的情況不同,具體情況如下:

協議版本密碼切換協議警告協議握手協議心跳協議應用數據協議TLS 1.3無✅(根據連接狀態不同進行加密,即一部分會加密)✅(一部分加密)❌✅TLS 1.2❌❌❌無✅

關於 TLS CCS 協議更多細節將在接下來的握手文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

協議數據結構如下:

C

 struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


3. TLS 警告協議

TLS 提供 alert 內容類型用來表示關閉信息和錯誤。與其他消息一樣,alert 消息也會根據當前連接狀態的進行加密。在 TLS 1.3 中,錯誤的嚴重性隱含在正在發送的警報類型中,並且可以安全地忽略 "level" 字段。"close_notify" alert 用於表示連接從一個方向開始有序的關閉。收到這樣的警報後,TLS 實現方應該表明應用程序的數據結束。

收到錯誤警報後,TLS 實現方應該向應用程序表示出現了錯誤,並且不允許在連接上發送或接收任何其他數據。

協議數據結構如下:

C

 enum { warning(1), fatal(2), (255) } AlertLevel;

struct {
AlertLevel level;
AlertDescription description;
} Alert;

經過 TLS 記錄層包裝以後,結構如下:


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • type:
  • 用於處理 TLS 握手層的高級協議。

C

 enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* RFC 6520 */
(255)
} ContentType;

ContentType 是對握手協議的封裝,消息頭類型和握手層子協議編號的對應關係如下:

消息頭類型

ContentTypechange_cipher_spec0x014alert0x015handshake0x016application_data0x017heartbeat (TLS 1.3 新增)0x018

  • legacy_record_version:
  • 對於除初始 ClientHello 之外的 TLS 1.3 實現生成的所有記錄(即,在 HelloRetryRequest 之後未生成的記錄),必須將其設置為 0x0303,其中出於兼容性目的,它也可以是0x0301。該字段在 TLS 1.3 中已經棄用,必須忽略它。在某些情況下,以前版本的 TLS 將在此字段中使用其他值。

在 TLS 1.3 中,version 為 0x0304,過去版本與 version 的對應關係如下:

協議版本versionTLS 1.30x0304TLS 1.20x0303TLS 1.10x0302TLS 1.00x0301SSL 3.00x0300

  • length:
  • TLSPlaintext.fragment 的長度(以字節為單位)。長度不得超過 2 ^ 14 字節。接收超過此長度的記錄的端點必須使用 "record_overflow" alert 消息終止連接。
  • fragment:
  • 正在傳輸的數據。此字段的值是透明的,它並被視為一個獨立的塊,由類型字段指定的更高級別協議處理。

當尚未使用密碼保護時,TLSPlaintext 結構是直接寫入傳輸線路中的。一旦記錄保護開始,TLSPlaintext 記錄將受到密碼保護。請注意,應用數據記錄不得寫入未受保護的連接中。所以在握手成功之前,是不能發送應用數據的。

TLS 記錄層協議在整個 TLS 協議中的定位如下:

  • 封裝處理 TLS 上層(握手層)中的平行子協議(TLS 1.3 中是 5 個子協議,TLS 1.2 及更老的版本是 4 個子協議),加上消息頭,打包往下傳遞給 TCP 處理。
  • 對上層應用數據協議進行密碼保護,對其他的子協議只是簡單封裝(即不加密)

關於 TLS 記錄層協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

2. TLS 密碼切換協議

注意:該協議在 TLS 1.3 標準規範中已經刪除,但是實際使用中為了兼容 TLS 老版本和一些消息中間件,所以實際傳輸中還可能用到這個協議。

change_cipher_spec (以下簡稱 CCS 協議) 協議,是 TLS 記錄層對應用數據是否進行加密的分界線。客戶端或者服務端一旦收到對端發來的 CCS 協議,就表明接下來傳輸數據過程中可以對應用數據協議進行加密了。

TLS 記錄層在處理上層 5 個協議(密碼切換協議,警告協議,握手協議,心跳協議,應用數據協議)的時候,TLS 不同版本對不同協議加密的情況不同,具體情況如下:

協議版本密碼切換協議警告協議握手協議心跳協議應用數據協議TLS 1.3無✅(根據連接狀態不同進行加密,即一部分會加密)✅(一部分加密)❌✅TLS 1.2❌❌❌無✅

關於 TLS CCS 協議更多細節將在接下來的握手文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

協議數據結構如下:

C

 struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


3. TLS 警告協議

TLS 提供 alert 內容類型用來表示關閉信息和錯誤。與其他消息一樣,alert 消息也會根據當前連接狀態的進行加密。在 TLS 1.3 中,錯誤的嚴重性隱含在正在發送的警報類型中,並且可以安全地忽略 "level" 字段。"close_notify" alert 用於表示連接從一個方向開始有序的關閉。收到這樣的警報後,TLS 實現方應該表明應用程序的數據結束。

收到錯誤警報後,TLS 實現方應該向應用程序表示出現了錯誤,並且不允許在連接上發送或接收任何其他數據。

協議數據結構如下:

C

 enum { warning(1), fatal(2), (255) } AlertLevel;

struct {
AlertLevel level;
AlertDescription description;
} Alert;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


TLS 1.3 和 TLS 1.2 在這個協議上改動很小,只是新增加了幾個枚舉類型。

TLS 1.2 的所有警告描述信息:

C

enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110), /* new */
(255)
} AlertDescription;

TLS 1.3 的所有警告描述信息:

C

 enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure_RESERVED(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
inappropriate_fallback(86),
user_canceled(90),
no_renegotiation_RESERVED(100),
missing_extension(109),
unsupported_extension(110),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),
(255)
} AlertDescription;

TLS 1.3 比 TLS 1.2 新增了 9 個警告描述信息:

C

 inappropriate_fallback(86),
missing_extension(109),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),

4. TLS 握手協議

握手協議是整個 TLS 協議簇中最最核心的協議,HTTPS 能保證安全也是因為它的功勞。

握手協議由多個子消息構成,服務端和客戶端第一次完成一次握手需要 2-RTT。

握手協議的目的是為了雙方協商出密碼塊,這個密碼塊會交給 TLS 記錄層進行密鑰加密。也就是說握手協議達成的“共識”(密碼塊)是整個 TLS 和 HTTPS 安全的基礎。

握手協議在 TLS 1.2 和 TLS 1.3 中發生了很大的變化。TLS 1.3 的 0-RTT 是一個全新的概念。兩個版本在密鑰協商上,密碼套件選擇上都有很大不同。

TLS 1.2 協議數據結構如下:

C

 enum {
hello_request(0),
client_hello(1),
server_hello(2),
certificate(11),
server_key_exchange (12),
certificate_request(13),
server_hello_done(14),
certificate_verify(15),
client_key_exchange(16),
finished(20)
(255)
} HandshakeType;
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;

TLS 1.3 協議數據結構如下:

C

 enum {
hello_request_RESERVED(0),
client_hello(1),
server_hello(2),
hello_verify_request_RESERVED(3),
new_session_ticket(4),
end_of_early_data(5),
hello_retry_request_RESERVED(6),
encrypted_extensions(8),
certificate(11),
server_key_exchange_RESERVED(12),
certificate_request(13),
server_hello_done_RESERVED(14),
certificate_verify(15),
client_key_exchange_RESERVED(16),
finished(20),
certificate_url_RESERVED(21),
certificate_status_RESERVED(22),
supplemental_data_RESERVED(23),
key_update(24),
message_hash(254),
(255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (Handshake.msg_type) {
case client_hello: ClientHello;
case server_hello: ServerHello;
case end_of_early_data: EndOfEarlyData;
case encrypted_extensions: EncryptedExtensions;
case certificate_request: CertificateRequest;
case certificate: Certificate;
case certificate_verify: CertificateVerify;
case finished: Finished;
case new_session_ticket: NewSessionTicket;
case key_update: KeyUpdate;
};
} Handshake;

經過 TLS 記錄層包裝以後,結構如下:


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • type:
  • 用於處理 TLS 握手層的高級協議。

C

 enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* RFC 6520 */
(255)
} ContentType;

ContentType 是對握手協議的封裝,消息頭類型和握手層子協議編號的對應關係如下:

消息頭類型

ContentTypechange_cipher_spec0x014alert0x015handshake0x016application_data0x017heartbeat (TLS 1.3 新增)0x018

  • legacy_record_version:
  • 對於除初始 ClientHello 之外的 TLS 1.3 實現生成的所有記錄(即,在 HelloRetryRequest 之後未生成的記錄),必須將其設置為 0x0303,其中出於兼容性目的,它也可以是0x0301。該字段在 TLS 1.3 中已經棄用,必須忽略它。在某些情況下,以前版本的 TLS 將在此字段中使用其他值。

在 TLS 1.3 中,version 為 0x0304,過去版本與 version 的對應關係如下:

協議版本versionTLS 1.30x0304TLS 1.20x0303TLS 1.10x0302TLS 1.00x0301SSL 3.00x0300

  • length:
  • TLSPlaintext.fragment 的長度(以字節為單位)。長度不得超過 2 ^ 14 字節。接收超過此長度的記錄的端點必須使用 "record_overflow" alert 消息終止連接。
  • fragment:
  • 正在傳輸的數據。此字段的值是透明的,它並被視為一個獨立的塊,由類型字段指定的更高級別協議處理。

當尚未使用密碼保護時,TLSPlaintext 結構是直接寫入傳輸線路中的。一旦記錄保護開始,TLSPlaintext 記錄將受到密碼保護。請注意,應用數據記錄不得寫入未受保護的連接中。所以在握手成功之前,是不能發送應用數據的。

TLS 記錄層協議在整個 TLS 協議中的定位如下:

  • 封裝處理 TLS 上層(握手層)中的平行子協議(TLS 1.3 中是 5 個子協議,TLS 1.2 及更老的版本是 4 個子協議),加上消息頭,打包往下傳遞給 TCP 處理。
  • 對上層應用數據協議進行密碼保護,對其他的子協議只是簡單封裝(即不加密)

關於 TLS 記錄層協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

2. TLS 密碼切換協議

注意:該協議在 TLS 1.3 標準規範中已經刪除,但是實際使用中為了兼容 TLS 老版本和一些消息中間件,所以實際傳輸中還可能用到這個協議。

change_cipher_spec (以下簡稱 CCS 協議) 協議,是 TLS 記錄層對應用數據是否進行加密的分界線。客戶端或者服務端一旦收到對端發來的 CCS 協議,就表明接下來傳輸數據過程中可以對應用數據協議進行加密了。

TLS 記錄層在處理上層 5 個協議(密碼切換協議,警告協議,握手協議,心跳協議,應用數據協議)的時候,TLS 不同版本對不同協議加密的情況不同,具體情況如下:

協議版本密碼切換協議警告協議握手協議心跳協議應用數據協議TLS 1.3無✅(根據連接狀態不同進行加密,即一部分會加密)✅(一部分加密)❌✅TLS 1.2❌❌❌無✅

關於 TLS CCS 協議更多細節將在接下來的握手文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

協議數據結構如下:

C

 struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


3. TLS 警告協議

TLS 提供 alert 內容類型用來表示關閉信息和錯誤。與其他消息一樣,alert 消息也會根據當前連接狀態的進行加密。在 TLS 1.3 中,錯誤的嚴重性隱含在正在發送的警報類型中,並且可以安全地忽略 "level" 字段。"close_notify" alert 用於表示連接從一個方向開始有序的關閉。收到這樣的警報後,TLS 實現方應該表明應用程序的數據結束。

收到錯誤警報後,TLS 實現方應該向應用程序表示出現了錯誤,並且不允許在連接上發送或接收任何其他數據。

協議數據結構如下:

C

 enum { warning(1), fatal(2), (255) } AlertLevel;

struct {
AlertLevel level;
AlertDescription description;
} Alert;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


TLS 1.3 和 TLS 1.2 在這個協議上改動很小,只是新增加了幾個枚舉類型。

TLS 1.2 的所有警告描述信息:

C

enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110), /* new */
(255)
} AlertDescription;

TLS 1.3 的所有警告描述信息:

C

 enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure_RESERVED(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
inappropriate_fallback(86),
user_canceled(90),
no_renegotiation_RESERVED(100),
missing_extension(109),
unsupported_extension(110),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),
(255)
} AlertDescription;

TLS 1.3 比 TLS 1.2 新增了 9 個警告描述信息:

C

 inappropriate_fallback(86),
missing_extension(109),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),

4. TLS 握手協議

握手協議是整個 TLS 協議簇中最最核心的協議,HTTPS 能保證安全也是因為它的功勞。

握手協議由多個子消息構成,服務端和客戶端第一次完成一次握手需要 2-RTT。

握手協議的目的是為了雙方協商出密碼塊,這個密碼塊會交給 TLS 記錄層進行密鑰加密。也就是說握手協議達成的“共識”(密碼塊)是整個 TLS 和 HTTPS 安全的基礎。

握手協議在 TLS 1.2 和 TLS 1.3 中發生了很大的變化。TLS 1.3 的 0-RTT 是一個全新的概念。兩個版本在密鑰協商上,密碼套件選擇上都有很大不同。

TLS 1.2 協議數據結構如下:

C

 enum {
hello_request(0),
client_hello(1),
server_hello(2),
certificate(11),
server_key_exchange (12),
certificate_request(13),
server_hello_done(14),
certificate_verify(15),
client_key_exchange(16),
finished(20)
(255)
} HandshakeType;
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;

TLS 1.3 協議數據結構如下:

C

 enum {
hello_request_RESERVED(0),
client_hello(1),
server_hello(2),
hello_verify_request_RESERVED(3),
new_session_ticket(4),
end_of_early_data(5),
hello_retry_request_RESERVED(6),
encrypted_extensions(8),
certificate(11),
server_key_exchange_RESERVED(12),
certificate_request(13),
server_hello_done_RESERVED(14),
certificate_verify(15),
client_key_exchange_RESERVED(16),
finished(20),
certificate_url_RESERVED(21),
certificate_status_RESERVED(22),
supplemental_data_RESERVED(23),
key_update(24),
message_hash(254),
(255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (Handshake.msg_type) {
case client_hello: ClientHello;
case server_hello: ServerHello;
case end_of_early_data: EndOfEarlyData;
case encrypted_extensions: EncryptedExtensions;
case certificate_request: CertificateRequest;
case certificate: Certificate;
case certificate_verify: CertificateVerify;
case finished: Finished;
case new_session_ticket: NewSessionTicket;
case key_update: KeyUpdate;
};
} Handshake;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


握手消息類型雖然有很多種,但是最終傳到 TLS 記錄層,有些會被合併到一條消息。

關於 TLS 握手協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

5. TLS 應用數據協議

應用數據協議就是 TLS 上層的各種協議,TLS 主要保護的數據就是應用數據協議的數據。

經過 TLS 記錄層包裝以後,結構如下:


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • type:
  • 用於處理 TLS 握手層的高級協議。

C

 enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* RFC 6520 */
(255)
} ContentType;

ContentType 是對握手協議的封裝,消息頭類型和握手層子協議編號的對應關係如下:

消息頭類型

ContentTypechange_cipher_spec0x014alert0x015handshake0x016application_data0x017heartbeat (TLS 1.3 新增)0x018

  • legacy_record_version:
  • 對於除初始 ClientHello 之外的 TLS 1.3 實現生成的所有記錄(即,在 HelloRetryRequest 之後未生成的記錄),必須將其設置為 0x0303,其中出於兼容性目的,它也可以是0x0301。該字段在 TLS 1.3 中已經棄用,必須忽略它。在某些情況下,以前版本的 TLS 將在此字段中使用其他值。

在 TLS 1.3 中,version 為 0x0304,過去版本與 version 的對應關係如下:

協議版本versionTLS 1.30x0304TLS 1.20x0303TLS 1.10x0302TLS 1.00x0301SSL 3.00x0300

  • length:
  • TLSPlaintext.fragment 的長度(以字節為單位)。長度不得超過 2 ^ 14 字節。接收超過此長度的記錄的端點必須使用 "record_overflow" alert 消息終止連接。
  • fragment:
  • 正在傳輸的數據。此字段的值是透明的,它並被視為一個獨立的塊,由類型字段指定的更高級別協議處理。

當尚未使用密碼保護時,TLSPlaintext 結構是直接寫入傳輸線路中的。一旦記錄保護開始,TLSPlaintext 記錄將受到密碼保護。請注意,應用數據記錄不得寫入未受保護的連接中。所以在握手成功之前,是不能發送應用數據的。

TLS 記錄層協議在整個 TLS 協議中的定位如下:

  • 封裝處理 TLS 上層(握手層)中的平行子協議(TLS 1.3 中是 5 個子協議,TLS 1.2 及更老的版本是 4 個子協議),加上消息頭,打包往下傳遞給 TCP 處理。
  • 對上層應用數據協議進行密碼保護,對其他的子協議只是簡單封裝(即不加密)

關於 TLS 記錄層協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

2. TLS 密碼切換協議

注意:該協議在 TLS 1.3 標準規範中已經刪除,但是實際使用中為了兼容 TLS 老版本和一些消息中間件,所以實際傳輸中還可能用到這個協議。

change_cipher_spec (以下簡稱 CCS 協議) 協議,是 TLS 記錄層對應用數據是否進行加密的分界線。客戶端或者服務端一旦收到對端發來的 CCS 協議,就表明接下來傳輸數據過程中可以對應用數據協議進行加密了。

TLS 記錄層在處理上層 5 個協議(密碼切換協議,警告協議,握手協議,心跳協議,應用數據協議)的時候,TLS 不同版本對不同協議加密的情況不同,具體情況如下:

協議版本密碼切換協議警告協議握手協議心跳協議應用數據協議TLS 1.3無✅(根據連接狀態不同進行加密,即一部分會加密)✅(一部分加密)❌✅TLS 1.2❌❌❌無✅

關於 TLS CCS 協議更多細節將在接下來的握手文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

協議數據結構如下:

C

 struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


3. TLS 警告協議

TLS 提供 alert 內容類型用來表示關閉信息和錯誤。與其他消息一樣,alert 消息也會根據當前連接狀態的進行加密。在 TLS 1.3 中,錯誤的嚴重性隱含在正在發送的警報類型中,並且可以安全地忽略 "level" 字段。"close_notify" alert 用於表示連接從一個方向開始有序的關閉。收到這樣的警報後,TLS 實現方應該表明應用程序的數據結束。

收到錯誤警報後,TLS 實現方應該向應用程序表示出現了錯誤,並且不允許在連接上發送或接收任何其他數據。

協議數據結構如下:

C

 enum { warning(1), fatal(2), (255) } AlertLevel;

struct {
AlertLevel level;
AlertDescription description;
} Alert;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


TLS 1.3 和 TLS 1.2 在這個協議上改動很小,只是新增加了幾個枚舉類型。

TLS 1.2 的所有警告描述信息:

C

enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110), /* new */
(255)
} AlertDescription;

TLS 1.3 的所有警告描述信息:

C

 enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure_RESERVED(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
inappropriate_fallback(86),
user_canceled(90),
no_renegotiation_RESERVED(100),
missing_extension(109),
unsupported_extension(110),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),
(255)
} AlertDescription;

TLS 1.3 比 TLS 1.2 新增了 9 個警告描述信息:

C

 inappropriate_fallback(86),
missing_extension(109),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),

4. TLS 握手協議

握手協議是整個 TLS 協議簇中最最核心的協議,HTTPS 能保證安全也是因為它的功勞。

握手協議由多個子消息構成,服務端和客戶端第一次完成一次握手需要 2-RTT。

握手協議的目的是為了雙方協商出密碼塊,這個密碼塊會交給 TLS 記錄層進行密鑰加密。也就是說握手協議達成的“共識”(密碼塊)是整個 TLS 和 HTTPS 安全的基礎。

握手協議在 TLS 1.2 和 TLS 1.3 中發生了很大的變化。TLS 1.3 的 0-RTT 是一個全新的概念。兩個版本在密鑰協商上,密碼套件選擇上都有很大不同。

TLS 1.2 協議數據結構如下:

C

 enum {
hello_request(0),
client_hello(1),
server_hello(2),
certificate(11),
server_key_exchange (12),
certificate_request(13),
server_hello_done(14),
certificate_verify(15),
client_key_exchange(16),
finished(20)
(255)
} HandshakeType;
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;

TLS 1.3 協議數據結構如下:

C

 enum {
hello_request_RESERVED(0),
client_hello(1),
server_hello(2),
hello_verify_request_RESERVED(3),
new_session_ticket(4),
end_of_early_data(5),
hello_retry_request_RESERVED(6),
encrypted_extensions(8),
certificate(11),
server_key_exchange_RESERVED(12),
certificate_request(13),
server_hello_done_RESERVED(14),
certificate_verify(15),
client_key_exchange_RESERVED(16),
finished(20),
certificate_url_RESERVED(21),
certificate_status_RESERVED(22),
supplemental_data_RESERVED(23),
key_update(24),
message_hash(254),
(255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (Handshake.msg_type) {
case client_hello: ClientHello;
case server_hello: ServerHello;
case end_of_early_data: EndOfEarlyData;
case encrypted_extensions: EncryptedExtensions;
case certificate_request: CertificateRequest;
case certificate: Certificate;
case certificate_verify: CertificateVerify;
case finished: Finished;
case new_session_ticket: NewSessionTicket;
case key_update: KeyUpdate;
};
} Handshake;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


握手消息類型雖然有很多種,但是最終傳到 TLS 記錄層,有些會被合併到一條消息。

關於 TLS 握手協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

5. TLS 應用數據協議

應用數據協議就是 TLS 上層的各種協議,TLS 主要保護的數據就是應用數據協議的數據。

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


TLS 記錄層會根據加密模式的不同在應用數據的末尾加上 MAC 校驗數據。

6. TLS 心跳協議

這個協議是 TLS 1.3 新增的。更加細節可以看這篇文章《TLS & DTLS Heartbeat Extension》,這篇文章是筆者根據 [RFC 6520] 翻譯的。感興趣的可以去看看這篇文章。這篇文章還涉及到了 DTLS 和 PMTU 發現。

協議數據結構如下:

C

 enum {
heartbeat_request(1),
heartbeat_response(2),
(255)
} HeartbeatMessageType;

struct {
HeartbeatMessageType type;
uint16 payload_length;
opaque payload[HeartbeatMessage.payload_length];
opaque padding[padding_length];
} HeartbeatMessage;

經過 TLS 記錄層包裝以後,結構如下:


"

Go語言中文網,致力於每日分享編碼、開源等知識,歡迎關注我,會有意想不到的收穫!

服務端開發避不開協議,避不開 HTTP 和 HTTPS 協議。對 HTTPS ,你真的清楚嗎?還是似是而非呢?這個系列希望能夠讓你更懂 HTTPS!

一、為什麼需要 HTTPS

HTTP1.1 有以下安全性問題:

  1. 使用明文(不加密)進行通信,內容可能會被竊聽;
  2. 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
  3. 無法證明報文的完整性,報文有可能遭篡改。

由於 HTTP 設計之初沒有考慮到這幾點,所以基於 HTTP 的這些應用都會存在安全問題。

1. 數據沒有加密

基於 TCP/IP 的網絡,網絡各處都會存在被監聽的風險。而且如果用 HTTP 協議進行通信,HTTP 本身沒有加密功能,所以也無法做到對通信整體(使用 HTTP 協議通信的請求和響應的內容)進行加密。即,HTTP 報文使用明文(指未經過加密的報文)方式發送。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


像上圖表示的那樣,在互聯網各個環節都可能被監聽。就算是加密通信,也能被監聽到通信內容,只不過監聽者看到的是密文。要解決 HTTP 上面 3 個大的安全問題,第一步就是要先進行加密通信。於是在傳輸層增加了一層 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 來加密 HTTP 的通信內容。

HTTPS (HTTP Secure) 並不是新協議,而是 HTTP 先和 SSL(Secure Sockets Layer 安全套接層)/ TLS (Transport Layer Security 安全層傳輸協議) 通信,再由 SSL/TLS 和 TCP 通信。也就是說 HTTPS 使用了隧道進行通信。

這個時候可能有同學會有疑問了,為什麼不直接對 HTTP 報文進行加密,這樣就不需要 SSL/TLS 這一層了。確實,如果直接對 HTTP 報文進行加密也可以做到加密通信,但是雖然解決了第一條,但是後面 2 條就不好解決了。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


就算直接對 HTTP 進行加密,HTTP 頭部也沒有加密,而頭部信息也會導致信息不安全。

2. 無法驗證通信對方的身份

基於 TCP 的 HTTP 雖然可以保證數據能完整的傳輸給對方,但是無法驗證通信對方的身份。HTTP 也由於協議的靈活性,應用的非常廣泛。通信的雙方無須驗證身份,服務器只要接收到能識別的請求,就會返回一個響應,一個 request 就一定會有一個 response。由於不確認通信對方,就會導致一些隱患:

  • 服務器無法驗證請求來自誰,是否是合法的客戶端。
  • 客戶端收到響應,也無法驗證是否是來自合法的服務器。
  • 無法阻止海量請求下的 Dos 拒絕攻擊(Denial of Service,拒絕服務攻擊)

3. 無法防止數據被篡改

HTTP 協議是無法保證數據的完整性的。所謂完整性指的是信息的準確度。若無法證明信息的完整性,也就意味著無法判斷信息是否準確。

客戶端和服務端面對收到的響應和請求,都只能無條件接受,HTTP 也無法知道請求或響應在傳輸過程中是否已經被篡改了,例如遭到了中間人攻擊(Man-in-the-Middle attack,MITM)。

HTTP 也有可以驗證報文完整性的方法,但是還是不可靠。比如利用 MD5 和 SHA-1 等散列值校驗的方法,用來確認文件的數字簽名。(MD5 和 SHA-1 低位數的已經不再安全了,會遭到碰撞攻擊,這個之後的文章再細緻分析)

有下載服務的 Web 網站也會提供 PGP (Pretty Good Privacy,完美隱私)創建的數字簽名及 MD5 算法生成的散列值。PGP 用來證明創建文件的數字簽名,MD5 是由單向函數生成的散列值。在 HTTP 的協議下,瀏覽器是無法知曉數據被篡改了,還是需要用戶自己查看。但是如果 PGP 和 MD5 在傳輸前就被篡改了,用戶拿到以後驗證對比發現是一致的,這種情況也沒法保證數據的完整正確性。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


通過使用 SSL,HTTPS 不僅能保證密文傳輸,重要的是還可以做到驗證通信方的身份,保證報文的完整性。完美的解決了 HTTP 在安全性上的三大缺陷。

二、部署 HTTPS 有何好處


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


可能讀者有這樣的疑惑,除了電商,金融,和錢打交道的網站必須要部署 HTTPS,其他的網站用不用 HTTPS 無所謂。筆者之前也有類似的想法,不過這個想法是錯誤的。

電商,金融,和錢打交道的網站必須要部署 HTTPS,這個毫無疑問,是為了防止用戶金錢上的損失,但是其他的網站呢?如果不部署 HTTPS,用裸的 HTTP,很容易遭到劫持,包括可能會被 ISP 插入小廣告。小廣告非常影響用戶體驗,如果是黃色廣告,還會影響用戶對這個網站的印象。另外用戶瀏覽了哪些頁面,用戶行為也很容易被分析出來,這種也算是洩露了用戶的隱私。

部署 HTTPS 有以下的好處:

1. 使用 HTTP/2 獲得更高的性能

內容交付網絡和網絡託管服務提供商正在開始推廣 HTTP/2。在 Velocity 的一次會議上,Load Impact 和 Mozilla 報告說,互聯網用戶可以通過 HTTP/2 優化比 HTTP/1.1 上的網站性能要好 50-70%。但是想用 HTTP/2 的性能優勢,必須要先部署 HTTPS,這個規定也算是對 HTTPS 的一個推廣。

2. 提高 SEO 排名

谷歌在 2014 年宣佈,支持 HTTPS 的網站將會有排名靠前的較大權重。

3. 更好的推薦數據

如果採用了谷歌的 Analytics 庫,它目前是強制運行在 HTTPS 上的,如果還是使用 HTTP,會由於 Analytics 不會獲取 HTTP 網站的 Referral 信息而導致數據不準確。

4. 更高的安全性

主流瀏覽器現在都會針對 HTTPS 網站增加小綠鎖標誌,沒有小綠鎖的網站,對用戶第一印象就不會很好。

5. 提高網站的信任和信譽

Chrome 62 版本以後,如果網頁有輸入框,沒有 HTTPS 的網頁一律都顯示為不安全。

6. HTLM5 新特性

在 Chrome 50版本以後,地理位置,音頻視頻接口必須要求運行在 HTTPS 上,目的是為了能保證數據傳輸安全。

7. iOS ATS 要求

蘋果為了推廣HTTPS,在 WWDC 2017 上也宣佈新的 App 必須要開啟 APS (App Transport Security)安全特性。

三、HTTPS 中的密碼學

1. 對稱密鑰加密

對稱密鑰加密(Symmetric-Key Encryption),加密和解密使用同一密鑰。

  • 優點:運算速度快;
  • 缺點:密鑰容易被獲取。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於對稱加密更加詳細的內容,可以看筆者之前寫的 《漫遊對稱加密算法》

2. 公開密鑰加密

公開密鑰加密(Public-Key Encryption),也稱為非對稱密鑰加密,使用一對密鑰用於加密和解密,分別為公開密鑰和私有密鑰。公開密鑰所有人都可以獲得,通信發送方獲得接收方的公開密鑰之後,就可以使用公開密鑰進行加密,接收方收到通信內容後使用私有密鑰解密。

  • 優點:更為安全;
  • 缺點:運算速度慢;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於公開密鑰加密更加詳細的內容,可以看筆者之前寫的 《翱遊公鑰密碼算法》

3. HTTPS 採用的加密方式

HTTPS 採用混合的加密機制,使用公開密鑰加密用於傳輸對稱密鑰,之後使用對稱密鑰加密進行通信。(下圖中的 Session Key 就是對稱密鑰)


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


4. 認證

HTTPS 通過使用 證書 來對通信方進行認證。

數字證書認證機構(CA,Certificate Authority)是客戶端與服務器雙方都可信賴的第三方機構。服務器的運營人員向 CA 提出公開密鑰的申請,CA 在判明提出申請者的身份之後,會對已申請的公開密鑰做數字簽名,然後分配這個已簽名的公開密鑰,並將該公開密鑰放入公開密鑰證書後綁定在一起。

進行 HTTPS 通信時,服務器會把證書發送給客戶端,客戶端取得其中的公開密鑰之後,先進行驗證,如果驗證通過,就可以開始通信。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


關於證書更加詳細的內容,可以看筆者之前寫的 《隨處可見的公鑰證書》

使用 OpenSSL 這套開源程序,每個人都可以構建一套屬於自己的認證機構,從而自己給自己頒發服務器證書。瀏覽器在訪問該服務器時,會顯示“無法確認連接安全性”或“該網站的安全證書存在問題”等警告消息。

5. 完整性

TLS / SSL 提供報文摘要功能來驗證完整性。

四、HTTPS 中的 TLS / SSL 協議


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


能讓 HTTPS 帶來安全性的是其背後的 TLS 協議。它源於九十年代中期在 Netscape 上開發的稱為安全套接字層(SSL)的協議。到 20 世紀 90 年代末,Netscape 將 SSL 移交給了 IETF,IETF 將其重命名為 TLS,並從此成為該協議的管理者。許多人仍將 Web 加密稱作 SSL,即使絕大多數服務已切換到僅支持 TLS。


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • 1995: SSL 2.0. 由 Netscape 提出,這個版本由於設計缺陷,並不安全,很快被發現有嚴重漏洞,已經廢棄。
  • 1996: SSL 3.0. 寫成 RFC,開始流行。目前(2015年)已經不安全,必須禁用。
  • 1999: TLS 1.0. 互聯網標準化組織 ISOC 接替 NetScape 公司,發佈了 SSL 的升級版 TLS 1.0 版。
  • 2006: TLS 1.1. 作為 RFC 4346 發佈。主要 fix 了 CBC 模式相關的如 BEAST 攻擊等漏洞。
  • 2008: TLS 1.2. 作為 RFC 5246 發佈。增進安全性。目前(2015 年)應該主要部署的版本,請確保你使用的是這個版本。
  • 2018:8月10日 RFC8446 TLS 1.3 協議正式發佈,它剔除了 TLS 1.2 協議中不安全的因素,極大地增強了協議的安全性和性能。

在 IETF 中,協議被稱為 RFC。TLS 1.0 是 RFC 2246,TLS 1.1 是 RFC 4346,TLS 1.2 是 RFC 5246。現在,TLS 1.3 為 RFC 8446。從 TLS 1.2 到 TLS 1.3,前前後後花了快 10 年的時間。RFC 通常按順序發佈,TLS 正式規範都是以 46 作為 RFC 編號的一部分更像是計劃好的,並非巧合。

TLS/SSL 協議位於應用層和傳輸層 TCP 協議之間。TLS 粗略的劃分又可以分為 2 層:

  • 靠近應用層的握手協議 TLS Handshaking Protocols
  • 靠近 TCP 的記錄層協議 TLS Record Protocol

TLS 握手協議還能細分為 5 個子協議:

  • change_cipher_spec (在 TLS 1.3 中這個協議已經刪除,為了兼容 TLS 老版本,可能還會存在)
  • alert
  • handshake
  • application_data
  • heartbeat (這個是 TLS 1.3 新加的,TLS 1.3 之前的版本沒有這個協議)

這些子協議之間的關係可以用下圖來表示:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇

1. TLS 記錄層協議

記錄層將上層的信息塊分段為 TLSPlaintext 記錄,TLSPlaintext 中包含 2^14 字節或更少字節塊的數據。根據底層 ContentType 的不同,消息邊界的處理方式也不同。TLS 1.3 中的規則比 TLS 1.2 中強制執行的規則更加嚴格。

握手消息可以合併為單個 TLSPlaintext 記錄,或者在幾個記錄中分段,前提是:

  • 握手消息不得與其他記錄類型交錯。也就是說,如果握手消息被分成兩個或多個記錄,則它們之間不能有任何其他記錄。
  • 握手消息絕不能跨越密鑰更改。實現方必須驗證密鑰更改之前的所有消息是否與記錄邊界對齊; 如果沒有,那麼他們必須用 "unexpected_message" alert 消息終止連接。因為 ClientHello,EndOfEarlyData,ServerHello,Finished 和 KeyUpdate 消息可以在密鑰更改之前立即發生,所以實現方必須將這些消息與記錄邊界對齊。

實現方絕不能發送握手類型的零長度片段,即使這些片段包含填充。

另外 Alert 消息禁止在記錄之間進行分段,並且多條 alert 消息不得合併為單個 TLSPlaintext 記錄。換句話說,具有 alert 類型的記錄必須只包含一條消息。

應用數據消息包含對 TLS 不透明的數據。應用數據消息始終應該受到保護。可以發送應用數據的零長度片段,因為它們可能作為流量分析對策使用。應用數據片段可以拆分為多個記錄,也可以合併為一個記錄。

C

 struct {
ContentType type;
ProtocolVersion legacy_record_version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


  • type:
  • 用於處理 TLS 握手層的高級協議。

C

 enum {
invalid(0),
change_cipher_spec(20),
alert(21),
handshake(22),
application_data(23),
heartbeat(24), /* RFC 6520 */
(255)
} ContentType;

ContentType 是對握手協議的封裝,消息頭類型和握手層子協議編號的對應關係如下:

消息頭類型

ContentTypechange_cipher_spec0x014alert0x015handshake0x016application_data0x017heartbeat (TLS 1.3 新增)0x018

  • legacy_record_version:
  • 對於除初始 ClientHello 之外的 TLS 1.3 實現生成的所有記錄(即,在 HelloRetryRequest 之後未生成的記錄),必須將其設置為 0x0303,其中出於兼容性目的,它也可以是0x0301。該字段在 TLS 1.3 中已經棄用,必須忽略它。在某些情況下,以前版本的 TLS 將在此字段中使用其他值。

在 TLS 1.3 中,version 為 0x0304,過去版本與 version 的對應關係如下:

協議版本versionTLS 1.30x0304TLS 1.20x0303TLS 1.10x0302TLS 1.00x0301SSL 3.00x0300

  • length:
  • TLSPlaintext.fragment 的長度(以字節為單位)。長度不得超過 2 ^ 14 字節。接收超過此長度的記錄的端點必須使用 "record_overflow" alert 消息終止連接。
  • fragment:
  • 正在傳輸的數據。此字段的值是透明的,它並被視為一個獨立的塊,由類型字段指定的更高級別協議處理。

當尚未使用密碼保護時,TLSPlaintext 結構是直接寫入傳輸線路中的。一旦記錄保護開始,TLSPlaintext 記錄將受到密碼保護。請注意,應用數據記錄不得寫入未受保護的連接中。所以在握手成功之前,是不能發送應用數據的。

TLS 記錄層協議在整個 TLS 協議中的定位如下:

  • 封裝處理 TLS 上層(握手層)中的平行子協議(TLS 1.3 中是 5 個子協議,TLS 1.2 及更老的版本是 4 個子協議),加上消息頭,打包往下傳遞給 TCP 處理。
  • 對上層應用數據協議進行密碼保護,對其他的子協議只是簡單封裝(即不加密)

關於 TLS 記錄層協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

2. TLS 密碼切換協議

注意:該協議在 TLS 1.3 標準規範中已經刪除,但是實際使用中為了兼容 TLS 老版本和一些消息中間件,所以實際傳輸中還可能用到這個協議。

change_cipher_spec (以下簡稱 CCS 協議) 協議,是 TLS 記錄層對應用數據是否進行加密的分界線。客戶端或者服務端一旦收到對端發來的 CCS 協議,就表明接下來傳輸數據過程中可以對應用數據協議進行加密了。

TLS 記錄層在處理上層 5 個協議(密碼切換協議,警告協議,握手協議,心跳協議,應用數據協議)的時候,TLS 不同版本對不同協議加密的情況不同,具體情況如下:

協議版本密碼切換協議警告協議握手協議心跳協議應用數據協議TLS 1.3無✅(根據連接狀態不同進行加密,即一部分會加密)✅(一部分加密)❌✅TLS 1.2❌❌❌無✅

關於 TLS CCS 協議更多細節將在接下來的握手文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

協議數據結構如下:

C

 struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


3. TLS 警告協議

TLS 提供 alert 內容類型用來表示關閉信息和錯誤。與其他消息一樣,alert 消息也會根據當前連接狀態的進行加密。在 TLS 1.3 中,錯誤的嚴重性隱含在正在發送的警報類型中,並且可以安全地忽略 "level" 字段。"close_notify" alert 用於表示連接從一個方向開始有序的關閉。收到這樣的警報後,TLS 實現方應該表明應用程序的數據結束。

收到錯誤警報後,TLS 實現方應該向應用程序表示出現了錯誤,並且不允許在連接上發送或接收任何其他數據。

協議數據結構如下:

C

 enum { warning(1), fatal(2), (255) } AlertLevel;

struct {
AlertLevel level;
AlertDescription description;
} Alert;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


TLS 1.3 和 TLS 1.2 在這個協議上改動很小,只是新增加了幾個枚舉類型。

TLS 1.2 的所有警告描述信息:

C

enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110), /* new */
(255)
} AlertDescription;

TLS 1.3 的所有警告描述信息:

C

 enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure_RESERVED(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
inappropriate_fallback(86),
user_canceled(90),
no_renegotiation_RESERVED(100),
missing_extension(109),
unsupported_extension(110),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),
(255)
} AlertDescription;

TLS 1.3 比 TLS 1.2 新增了 9 個警告描述信息:

C

 inappropriate_fallback(86),
missing_extension(109),
certificate_unobtainable_RESERVED(111),
unrecognized_name(112),
bad_certificate_status_response(113),
bad_certificate_hash_value_RESERVED(114),
unknown_psk_identity(115),
certificate_required(116),
no_application_protocol(120),

4. TLS 握手協議

握手協議是整個 TLS 協議簇中最最核心的協議,HTTPS 能保證安全也是因為它的功勞。

握手協議由多個子消息構成,服務端和客戶端第一次完成一次握手需要 2-RTT。

握手協議的目的是為了雙方協商出密碼塊,這個密碼塊會交給 TLS 記錄層進行密鑰加密。也就是說握手協議達成的“共識”(密碼塊)是整個 TLS 和 HTTPS 安全的基礎。

握手協議在 TLS 1.2 和 TLS 1.3 中發生了很大的變化。TLS 1.3 的 0-RTT 是一個全新的概念。兩個版本在密鑰協商上,密碼套件選擇上都有很大不同。

TLS 1.2 協議數據結構如下:

C

 enum {
hello_request(0),
client_hello(1),
server_hello(2),
certificate(11),
server_key_exchange (12),
certificate_request(13),
server_hello_done(14),
certificate_verify(15),
client_key_exchange(16),
finished(20)
(255)
} HandshakeType;
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;

TLS 1.3 協議數據結構如下:

C

 enum {
hello_request_RESERVED(0),
client_hello(1),
server_hello(2),
hello_verify_request_RESERVED(3),
new_session_ticket(4),
end_of_early_data(5),
hello_retry_request_RESERVED(6),
encrypted_extensions(8),
certificate(11),
server_key_exchange_RESERVED(12),
certificate_request(13),
server_hello_done_RESERVED(14),
certificate_verify(15),
client_key_exchange_RESERVED(16),
finished(20),
certificate_url_RESERVED(21),
certificate_status_RESERVED(22),
supplemental_data_RESERVED(23),
key_update(24),
message_hash(254),
(255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (Handshake.msg_type) {
case client_hello: ClientHello;
case server_hello: ServerHello;
case end_of_early_data: EndOfEarlyData;
case encrypted_extensions: EncryptedExtensions;
case certificate_request: CertificateRequest;
case certificate: Certificate;
case certificate_verify: CertificateVerify;
case finished: Finished;
case new_session_ticket: NewSessionTicket;
case key_update: KeyUpdate;
};
} Handshake;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


握手消息類型雖然有很多種,但是最終傳到 TLS 記錄層,有些會被合併到一條消息。

關於 TLS 握手協議更多細節將在接下來的文章中詳細分析。也會對 TLS 1.2 和 TLS 1.3 展開對比。

5. TLS 應用數據協議

應用數據協議就是 TLS 上層的各種協議,TLS 主要保護的數據就是應用數據協議的數據。

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


TLS 記錄層會根據加密模式的不同在應用數據的末尾加上 MAC 校驗數據。

6. TLS 心跳協議

這個協議是 TLS 1.3 新增的。更加細節可以看這篇文章《TLS & DTLS Heartbeat Extension》,這篇文章是筆者根據 [RFC 6520] 翻譯的。感興趣的可以去看看這篇文章。這篇文章還涉及到了 DTLS 和 PMTU 發現。

協議數據結構如下:

C

 enum {
heartbeat_request(1),
heartbeat_response(2),
(255)
} HeartbeatMessageType;

struct {
HeartbeatMessageType type;
uint16 payload_length;
opaque payload[HeartbeatMessage.payload_length];
opaque padding[padding_length];
} HeartbeatMessage;

經過 TLS 記錄層包裝以後,結構如下:


HTTPS 協議細節知多少?HTTPS 溫故知新(一)——開篇


根據 [RFC6066] 中的定義,在協商的時候,HeartbeatMessage 的總長度不得超過 2 ^ 14 或 max_fragment_length。

HeartbeatMessage 的長度為 TLS 的TLSPlaintext.length 和 DTLS 的 DTLSPlaintext.length。此外,類型 type 字段的長度是 1 個字節,並且 payload_length 的長度是 2 個字節。因此,padding_length 是TLSPlaintext.length - payload_length - 3 用於 TLS,DTLSPlaintext.length - payload_length - 3 用於 DTLS。padding_length 必須至少為 16。

HeartbeatMessage 的發送方必須使用至少 16 個字節的隨機填充。必須忽略收到的HeartbeatMessage 消息的填充。

五. 接下來

本篇文章作為 HTTPS 的開篇文章,分析了 HTTTPS 協議存在的必要性,HTTPS 帶來的好處,HTTPS 安全的本質,以及 TLS 各個子協議之間的關係和作用。

接下來的幾篇文章將會詳細的對比 TLS 1.2 和 TLS 1.3 在握手協議上的差別,在記錄層上的差別,在密鑰導出上的差別,以及 TLS 1.3 新增的 0-RTT 到底是怎麼回事。


Reference:

《圖解 HTTP》

《深入淺出 HTTPS》

TLS 1.3 規範 [RFC 8446]

TLS 1.2 規範 [RFC 5246]

GitHub Repo:Halfrost-Field

Follow: halfrost · GitHub

Source: https://halfrost.com/HTTPS_begin/

本文作者:於德志 (@halfrost),原創授權發佈

"

相關推薦

推薦中...