從崩潰的選課系統,論為什麼更安全的 HTTPS 協議沒有被全面採用

🎓 盡人事,聽天命。部落客東南大學研究生在讀,熱愛健身和籃球,正在為兩年後的秋招準備中,樂於分享技術相關的所見所得,關注公眾號 @ 飛天小牛肉,第一時間獲取文章更新,成長的路上我們一起進步

🎁 本文已收錄於 CS-Wiki(Gitee 官方推薦項目,現已 0.9k star),致力打造完善的後端知識體系,在技術的路上少走彎路,歡迎各位小夥伴前來交流學習

0. 前言

上一篇文章詳細講解了 HTTP 的相關原理,我們已經了解到了 HTTP 具有非常優秀和方便的一面,然而,HTTP 並非一個安全的協議。大家平常瀏覽網頁的時候應該也能注意到,使用 HTTP 協議的網站,瀏覽器都會認定這是一個不安全的網站,提醒用戶注意防範(即便這是我們學校的選課系統)。

當然,這個不安全的含義指的是你在該網頁輸入的資訊可能會被外界攻擊者以非正常手段竊取,而不是說會被這個網頁的開發者獲取,畢竟瀏覽器咋能判斷這個網頁開發者是否存有異心,這個需要用戶自行判斷(手動滑稽 😮)

那麼為了克服 HTTP 的缺點,確保 Web 的安全,HTTPS 就應用而生了。可以看見,使用 HTTPS 協議的網頁,地址欄前面都會有把小鎖,表示這是一個加密安全的網站,你的資訊發送到此站點時是保密的。而且 Google、Baidu 等搜索引擎巨頭對於 HTTPS 網站都會給到更好的搜索排名。

本文會先解釋 HTTP 為什麼是不安全的,然後講解 HTTPS 為了保證 Web 的安全提供了哪些手段,最後再揭曉謎底,為什麼更安全的 HTTPS 協議在互聯網上沒有被全面採用。

1. 不安全的 HTTP

通過上面那張圖我們已經知道,對於使用 HTTP 的網站,瀏覽器就會提醒我們請勿在此網站上輸入任何敏感資訊,否則可能會被攻擊者竊取。沒錯,這就是 HTTP 協議不安全的表現,而且,僅僅是其中之一,HTTP 的不安全性體現在很多方面,例舉如下:

  • 通訊使用明文(不加密),內容可能被竊聽

  • 不驗證通訊對方的身份,因此有可能遭遇偽裝

  • 無法證明報文的完整性,所以有可能被篡改

當然,這些問題不僅在 HTTP 上出現,其他未加密的協議中也存在類似問題

下面我們詳細分析下上述問題出現的原因。

① 內容被竊聽

所謂互聯網,是由能連接到全世界的網路組成的,萬物互聯,無論世界哪個角落的伺服器在和客戶端進行通訊時,在此通訊線路上的網路設備、光纜、電腦都可能會遭到惡意窺視行為。也就是說,互聯網上的任何角落都存在通訊內容被竊聽的風險。

而由於 HTTP 本身不具備加密的功能,所以也無法做到對 HTTP 請求和響應報文進行加密。

但是!即使是加密過的通訊內容,也會被窺視到,這點和未加密的通訊是相同的。只能說經過加密後的內容,即便被攻擊者窺視到,他也可能無法破解其中的含義罷了,但是加密處理後的報文資訊本身還是會被看到的,這點大家不要混淆了。加密後的內容尚且如此,更別說未加密的了。

② 身份被偽裝

HTTP 的請求和響應不會對通訊方進行確認,也就是說任何人都可以發起請求,而伺服器對請求者來者不拒,只要接收到請求,就會返回一個響應。

顯然,正是由於 HTTP 的這種簡單性,導致了如下隱患:

1)客戶端發送的 HTTP 請求報文可能到達的並非真正的目的伺服器,可能是已偽裝的伺服器

2)伺服器返回的 HTTP 響應報文可能也並沒有被正確的客戶端所接收,可能是已偽裝的客戶端

3)無法確定正在通訊的對方是否具備訪問許可權

4)無法判定請求來自何方,出自誰手

5)即使是無意義的請求也會照單全收

③ 報文被篡改

HTTP 無法證明報文的完整性,所謂完整性就是指資訊的準確度。若無法證明完整性,在 HTTP 請求或響應 送出之後直到對方接收的這段時間內,即使請求或響應的內容遭到攻擊者篡改,也沒有辦法獲悉。

通俗來說,HTTP 沒有辦法確認發送出去的請求和接收到的請求是否一致

舉個例子,你從某個使用 HTTP 的非正規網站上下載微信 APP,存放在伺服器上的文件確實是微信 APP,但是,在你下載的過程當中,攻擊者攻擊了這個網站,你正在傳輸的文件內容被篡改成了其他文件,而在這個過程中,你是完全察覺不到的。

像這樣的在請求或響應在傳輸途中,遭受攻擊者攔截並篡改內容的攻擊稱為中間人攻擊(Main-in-the-Middle attack, MITM)。

2. 安全的 HTTPS

HTTPS 協議並非應用層的一個新協議,只是 HTTP 通訊介面部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協議代替而已。

通常 HTTP 是直接和 TCP 進行通訊的,當使用 SSL 時,則演變成先和 SSL 通訊,再由 SSL 和 TCP 進行通訊。簡而言之。所謂 HTTPS,就是身批 SSL 協議外殼的 HTTP

在採用 SSL 後,HTTP 就擁有了加密、證書和完整性保護等功能,而這些功能正是用來解決我們上述所說的 HTTP 不安全問題的。

另外,SSL 是獨立於 HTTP 協議的,所有運行在應用層的協議都可以配合 SSL 協議使用。可以說,SSL 協議是當今世界上應用最為廣泛的網路安全技術。

那麼,針對上述 HTTP 的三個安全性問題,我們來看看 HTTPS 或者說 SSL 到底提供了哪些解決方案。

① 加密

這個上文也提到了,既然無法阻止被竊聽,那麼我就把我的內容加密起來,讓你無法破解。那麼,既然發送方對通訊內容進行了加密,接收方接收到這個被加密過的內容,一定要知道對應的解密手段。

在講解下述的幾種加密方法之前,我們先理解密鑰的概念。所謂密鑰,就是鑰匙,加密方有一把密鑰,用來上鎖,解密方也擁有一把密鑰,用來解鎖。而且加密方和解密方使用的密鑰不一定是同一把。

共享密鑰加密

加密和解密使用同一密鑰的方式稱為共享密鑰加密(Common Key crypto system),也稱做對稱密鑰加密(這個更好理解)。

以共享密鑰加密時必須將密鑰也發送給對方。顯然,如果通訊雙方都各自持有同一個密鑰,且沒有別人知道,則兩方的通訊安全是可以被保證的(除非密鑰被破解)。

那麼,最大的問題就是如何保證這個密鑰的安全傳輸,不被外部攻擊者知道。如果由伺服器生成一個密鑰並傳輸給瀏覽器,這個傳輸過程中密鑰被攻擊者劫持,那麼之後攻擊者就能用這把密鑰解開雙方傳輸的任何內容。

發送密鑰就有被竊聽的危險,但不發送,對方就不能解密。怎麼樣才能安全的發送密鑰?解決這個問題,我們就需要公開密鑰加密(非對稱密鑰加密)。

公開密鑰加密

公開密鑰加密很好的解決了共享密鑰加密的困難。

公開密鑰加密需要一組非對稱的密鑰對,分別是公鑰 public key 和私鑰 private key。顧名思義,公鑰可以隨意發布,任何人都可以獲得,而私鑰不能讓除通訊雙方外的其他任何人知道。這兩個密鑰是成對出現的,公鑰加密的內容需要對應的私鑰解密

舉個例子:客戶端(瀏覽器)想要給網站伺服器發送消息

  • 首先,網站伺服器持有一組公鑰和私有,它會把自己的公鑰明文傳輸給客戶端

  • 客戶端利用這個公鑰給自己的消息進行加密,然後傳輸給伺服器,這時候就算被攻擊者截獲,由於攻擊者沒有對應的私鑰也無法解密該內容

  • 網站伺服器收到後,使用這個公鑰對應的私鑰進行解密

利用這種方式,不需要發送解密需要的私鑰,也就不必擔心私鑰被攻擊者盜走

混合加密方式

上述公開密鑰加密的方式雖然安全,但是相比於不那麼安全的共享密鑰加密方式來說,其處理速度要慢很多。HTTPS 綜合這兩種加密方式的優勢,使用共享密鑰加密要發送的資訊,使用公開密鑰加密這個共享密鑰,這樣就減少了公開加密的次數。舉個例子:

  • 某網站伺服器擁有一組用於公開密鑰加密的非對稱密鑰:公鑰 A1、私鑰 A2

  • 瀏覽器向網站伺服器請求,伺服器把公鑰 A1 明文給傳輸瀏覽器

  • 接收到這把公鑰 A1 後,瀏覽器隨機生成一個用於共享密鑰加密(對稱加密)的密鑰 X,用公鑰 A1 加密後傳給伺服器。這個階段,即便被攻擊者截獲,由於攻擊者沒有對應的私鑰也無法解密該內容

  • 伺服器拿到後用對應的私鑰 A2 解密得到密鑰 X(以上這些階段就是公開密鑰加密)

  • 這樣雙方就都擁有密鑰 X 了,且別人無法知道它。之後雙方之間所有的數據傳輸都使用密鑰 X 進行加密和解密即可(這個階段就是共享密鑰加密)

② 數字證書

遺憾的是,上述混合加密的方式仍然還是有漏洞的。攻擊者(中間人)的確無法得到瀏覽器生成的對稱密鑰 X,這個密鑰本身被公鑰 A1 加密,只有使用伺服器擁有的私鑰 A2 才能解密。但是!攻擊者完全不需要拿到伺服器私有的私鑰 A2 就能劫持資訊。舉個例子:

  • 某網站伺服器擁有一組用於公開密鑰加密的非對稱密鑰:公鑰 A1、私鑰 A2

  • 瀏覽器向網站伺服器請求,伺服器把公鑰 A1 明文給傳輸瀏覽器

  • 攻擊者劫持到公鑰 A1,保存下來,把數據包中的公鑰 A1 替換成自己偽造的公鑰 B1(它當然也擁有公鑰 B1 對應的私鑰 B2)

  • 瀏覽器隨機生成一個用於對稱加密的密鑰 X,用攻擊者的公鑰 B1(伺服器此時不知道自己的公鑰被替換了)加密後傳給伺服器

  • 攻擊者劫持後用自己的私鑰 B2 解密就得到了密鑰 X。然後再用伺服器的公鑰 A1 加密後傳給伺服器

  • 伺服器接收到攻擊者用公鑰 A1 加密的資訊後,用對應的私鑰 A2 解密得到密鑰 X

這樣在客戶端瀏覽器和網站伺服器都沒有發現異常的情況下,攻擊者得到了對稱密鑰 X。此後客戶端和瀏覽器雙方通過對稱密鑰 X 加密發送的任何內容,攻擊者都可以輕鬆破解。

 

上述過程就是典型的中間人攻擊,其根本原因是瀏覽器客戶端無法確認自己收到的公鑰是不是真正的網站伺服器的。那麼下一步就是解決這個問題:❓ 如何證明瀏覽器客戶端收到的公鑰一定是該網站伺服器的公鑰?防止伺服器和客戶端的身份被偽裝。

其實很簡單,大家想一下在現實生活中,如何證明小明說出的身份證號確實是它自己的,怎麼辦?看看小明的身份證就可以了。身份證是由誰頒發的?政府機構。那麼這裡政府機構就起到了公信的作用,它本身的權威可以對一個人的身份資訊作出證明。

對應的,互聯網中也有這麼一個公信機構,數字證書認證機構 Certificate Authority, CA。所謂公信機構,就是客戶端和瀏覽器都信賴的第三方機構。

網站伺服器在使用 HTTPS 前,需要向 CA 申請頒發數字證書,數字證書里有證書持有者、證書持有者的公鑰等資訊。伺服器把數字證書明文傳輸給瀏覽器客戶端,然後瀏覽器從證書里取出伺服器的公鑰就可以了。

然而這裡又有一個顯而易見的問題:證書本身的傳輸過程中,如何防止被篡改?即如何證明證書本身的真實性? 數字證書怎麼防偽呢?

③ 數字簽名

數字證書認證機構 CA 在判明提出申請者的身份之後,會對其申請的公開密鑰做數字簽名,然後將數字簽名和公開密鑰放入數字證書。而客戶端在收到伺服器發送來的數字證書後,對證書上面的數字簽名進行驗證,如何這個數字簽名和證書上的原始公開密鑰 Hash 後的結果一致,那麼客戶端便可明確兩件事情:

  • 認證伺服器的公開密鑰的是真實有效的數字證書認證機構

  • 伺服器的公開密鑰是值得信賴的

OK,這麼說還不太清楚,我們先來了解什麼是數字簽名?

數字證書認證機構 CA 把要傳送的明文資訊(也就是申請認證的網站伺服器的公鑰)通過 Hash 演算法得出摘錄資訊 MIC(摘錄技術),再用自己的私鑰對 MIC 值進行加密,就得到了得到數字簽名。

解釋一下:認證機構一般會持有一組公鑰 A1 和私鑰 A2,為了確保證書的安全性,瀏覽器客戶端通常會在內部事先植入常用認證機構的公鑰 A1,認證機構在頒發數字證書的時候,會用自己的私鑰 A2 對數字簽名進行加密。而瀏覽器接收到數字證書後,先利用事先存儲好的公鑰 A1 解密數字簽名,再對數字簽名進行驗證。

下面是這個過程的總結提煉,大家配合圖片直觀理解一下。

1)CA 頒發數字證書給網站的過程

  • CA 擁有非對稱加密的私鑰和公鑰

  • 網站申請數字證書,並發送自己的公開密鑰 A

  • CA 對網站的公開密鑰 A 進行 Hash 得到摘錄資訊 MIC

  • 對 MIC 值用 CA 的私鑰加密,繼而得到數字簽名

  • 將數字簽名和網站的公開密鑰 A 放進數字證書發放給網站

 

2)瀏覽器客戶端驗證網站數字證書的過程

  • 瀏覽器客戶端接收到網站伺服器發來的數字證書,得到網站的公鑰 A 和數字簽名 S1

  • 瀏覽器使用事先植入的 CA 機構的公鑰對 S1 進行解密,得到 S2

  • 用數字證書里說明的 Hash 演算法對網站的公鑰 A 進行 Hash 得到 A2。

  • 比較 S2 是否等於 A2,若相等則表示證書可信。於是瀏覽器就可以放心的取出數字證書中的網站公鑰 A 進行使用

3. 為什麼 HTTPS 沒有被全面採用

回到文章標題,既然 HTTPS 安全可靠,那為什麼不所有的 Web 網站都使用 HTTPS 呢?

其中一個原因就是,由於使用了加密通訊, 相比於純文本通訊的 HTTP 來說,HTTPS 會消耗掉更多的 CPU 及記憶體資源,如果每次通訊都加密,會消耗掉非常多的資源,平攤到一台電腦上時,能夠處理的請求數量必定也會隨之減少。一些國際大型網站比如維基百科等,在啟用 HTTPS 前都會先考慮自己伺服器資源和計算能力是否可以承載 HTTPS。

因此,如果是非敏感資訊,使用 HTTP 通訊也無妨。只有在涉及個人敏感資訊等數據時,才需要使用 HTTPS。

另外,開啟 HTTPS 需要申請 SSL 證書,高額的證書申購費用會讓很多網站開發者望而卻步。

看到這裡,不知道大家能不能夠理解為什麼基本上所有學校的選課系統全是 HTTP 了:

  • 首先,大部分選課系統基本都需要校園網或者 VPN 才能夠登錄,不需要考慮被外界攻擊或者資訊泄露問題

  • 其次,即便使用的是 HTTP,選課系統開放的初期猛量的高並發尚且會讓伺服器崩潰,就甭說 HTTPS 了

所以綜合來說,校內選課系統完全沒必要增加額外的運行和維護成本來使用 HTTPS。

 

🎉 關注公眾號 | 飛天小牛肉,即時獲取更新

  • 部落客東南大學研究生在讀,利用課餘時間運營一個公眾號『 飛天小牛肉 』,2020/12/29 日開通,專註分享電腦基礎(數據結構 + 演算法 + 電腦網路 + 資料庫 + 作業系統 + Linux)、Java 基礎和面試指南的相關原創技術好文。本公眾號的目的就是讓大家可以快速掌握重點知識,有的放矢。希望大家多多支援哦,和小牛肉一起成長 😃

  • 並推薦個人維護的開源教程類項目: CS-Wiki(Gitee 推薦項目,現已 0.9k star), 致力打造完善的後端知識體系,在技術的路上少走彎路,歡迎各位小夥伴前來交流學習 ~ 😊