網絡基礎08 HTTPS

SSL/TLS協議

HTTPS(HTTP Secure)是HTTP加上加密、認證和完整性保護。不是一種新的協議,只是在HTTP通信接口部分用了SSL和TLS協議代替,也就是說在HTTP與TCP之間增加了SSL,HTTP與SSL通信,再由SSL與TCP通信。

TLS是SSL協議的升級版, 目前應用最廣泛的是TLS1.0和SSL3.0。

不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文傳播,帶來了三大風險:

  1. 竊聽風險(eavesdropping):第三方可以獲知通信內容。
  2. 篡改風險(tampering):第三方可以修改通信內容。
  3. 冒充風險(pretending):第三方可以冒充他人身份參與通信。

SSL/TLS協議是爲了解決這三大風險而設計的,希望達到:

  1. 所有信息都是加密傳播,第三方無法竊聽。
  2. 具有校驗機制,一旦被篡改,通信雙方會立刻發現。
  3. 配備身份證書,防止身份被冒充。

SSL/TLS協議的基本思路是採用了公開密鑰加密法,客戶端首先向服務器索要公鑰,然後用公鑰加密信息,服務器收到密文後,用自己的私鑰解密。

這裏面有兩個問題:

(1)如何保證公鑰不被篡改

將公鑰放在CA機構頒發的數字證書中,客戶端收到服務器的公鑰時會使CA機構內置在瀏覽器中的公鑰進行驗證。因此只要數字證書是可信的,公鑰就是可信的

(2)公鑰加密計算量太大,如何減少耗用時間

在建立連接階段使用公開密鑰加密計算,生成一個“對話密鑰”,在隨後的通話期間信息由“對話密鑰”進行共享密鑰加密。共享密鑰加密是對稱加密,運算速度很快,而服務器公鑰只用於加密“對話密鑰”本身,這樣就減少了加密運算的時間。

HTTPS的工作模式

非對稱加密在性能上不如對稱加密,所以HTTPS採取了對稱加密和非對稱加密相結合的工作模式:公鑰私鑰主要用於傳輸對稱加密的祕鑰,而真正的雙方大數據量的通信都是通過對稱加密進行的

非對稱加密需要通過證書和權威機構來驗證公鑰的合法性。

HTTPS的握手機制

HTTPS的握手相當於SSL/TLS協議的握手和TCP協議的握手,這裏主要介紹的是SSL/TLS的握手。

SSL/TLS的握手階段設涉及四次通信,這四次通信都是明文的:

(1)客戶端發出請求(ClientHello)

客戶端先想服務器發出加密通信的請求,提供一些基本信息,比如支持的TLS/SSL版本、用於生成“對話密鑰”的隨機數,支持的加密方法等。

(2)服務器迴應(ServerHello)

服務器收到客戶端請求後,向客戶端發出迴應,包含用於協商建立SSL通信的信息,比如確認使用的加密通信加密版本,服務器證書(包含服務器的公鑰)、確認使用的加密方法、服務器生成的用來生成“對話密鑰“的隨機數

此外,如果服務器需要確認客戶端身份,就會再包含一項請求,要求客戶端提供“客戶端證書”。比如金融機構往往只允許認證客戶連入自己的網絡,就會想正式客戶提供USB密鑰,裏面包含了一張客戶端證書。

(3)客戶端迴應

客戶端收到服務器的迴應後,首先驗證服務器證書,如果證書不是可信機構頒佈,或者證書的域名與實際域名不一致,或者證書已經過期,就會想訪問者顯示警告,由其選擇是否還要繼續通信。

如果證書沒有問題,客戶端就會從證書中取出服務器的公鑰,然後向服務器發送下面三項信息:

1. 一個隨機數(pre-master-key)。這個隨機數會用服務器公鑰加密
2. 編碼改變通知,表示隨後的信息都將用雙方商定的加密方法和密鑰發送
3. 客戶端握手結束通知,表示客戶端的握手階段結束。這一項同時也是前面發送的所有內容的hash值,用來供服務器校驗

到此爲止,握手階段已經有了三個隨機數,隨後,雙方就會用實現商定的加密方法,用着三個隨機數各自生成用於本次會話加密的同一把“會話密鑰”。爲什麼一定要用三個隨機數呢?

SSL協議中的證書是靜態的,因此十分有必要引入一種隨機因素來保證每次會話協商出來的密鑰的隨機性。所以不管是客戶端還是服務器,都需要隨機數,這樣每次會話生成的密鑰纔不會每次都一樣。

對於RSA密鑰交換算法來說,pre-master-key本身是一個隨機數,再加上Hello消息中的隨機數,三個隨機數通過密鑰到初七最終導出一個對稱密鑰。

SSL協議不信任每個主機都能產生完全隨機的隨機數,如果隨機數不隨機,那麼對話密鑰就有可能被猜出來。而三個隨機數一同生成的密鑰就不容易被猜出來了,一個僞隨機可能完全不隨機,可是三個僞隨機就十分接近隨機了,每增加一個自由度,隨機性增加的可不是一。

此外,如果在第二步服務器要求客戶端提供證書,那麼客戶端在這一步還會發送證書及相關信息。

(4)服務器的最後迴應

服務器收到客戶端的第三個隨機數pre-master-key後,計算生成本次會話用的“會話密鑰”,然後向客戶端發最後發送下面信息

1. 編碼改變通知,表示表示隨後的信息都將用雙方商定的加密方法和密鑰發送
2. 服務器握手結束通知,表示服務器的握手階段已經結束。這一項同時也是前面發送的所有內容的hash值,用來供客戶端校驗。

至此,整個握手階段全部結束,接下來客戶端與服務器進入加密通信,就是完全使用HTTP協議,只不過使用“對話密鑰”加密內容。

數字證書

公開密鑰加密還有一個問題:每個服務器都可以生成自己的私鑰和公鑰,客戶端並沒有辦法確定自己接收到到的公鑰是否真的是目標網站的公鑰,還是被替換過。

即:如何證明服務器下發的公鑰沒有被替換?

現在通用的解決方法就是通過數字證書認證機構(Certificate Authority,CA)頒發的公開密鑰證書來解決這個問題。

CA會爲提交申請的服務器的公鑰做認證,CA利用自己的私鑰,對服務器的公鑰和一些相關信息一起加密,生成數字證書(Digital Certificate)。這樣服務器在建立HTTPS連接時不再直接下發公鑰,而是下發包含着服務器公鑰(經過CA私鑰加密過的)的數字證書。

瀏覽器會將CA的公開密鑰事先內置到瀏覽器當中(避免了這個證書在傳遞中出現的問題)。所以客戶端收到信息後,會利用CA的公鑰解密數字證書,拿到服務器的真實的公鑰。

拿到真實的公鑰後,客戶端(瀏覽器)會根據內置的“證書管理器”來驗證公鑰是否真的屬於目標網站

客戶端的“證書管理器”有`受信任的根證書辦法機構”列表,客戶端會根據這個列表,查看解開數字證書的公鑰是否在列表內。

如果證書不是可信機構頒佈,或者證書的域名與實際域名不一致,或者證書已經過期,就會想訪問者顯示警告,由其選擇是否還要繼續通信。

SSL延遲

HTTP耗時 = TCP握手(3次)

HTTPS耗時 = TCP握手(3次) + SSL握手

HTTPS肯定比HTTP耗時,這就叫SSL延遲。

從運行結果可以看到,SSL握手的耗時大概是TCP握手的三倍。也就是說,在建立連接的階段,HTTPS連接比HTTP連接要長3倍的時間,具體數字取決於CPU的快慢和網絡狀況。

所以,如果是對安全性要求不高的場合,爲了提高網頁性能,建議不要採用保密強度很高的數字證書。一般場合下,1024位的證書已經足夠了,2048位和4096位的證書將進一步延長SSL握手的耗時。

升級HTTPS

(1)獲取證書

升級到HTTPS協議的第一步,就是要獲得一張證書。

證書是一個二進制文件,裏面包含經過認證的網站公鑰和一些元數據,要從經銷商購買。

  • GoGetSSL.com
  • SSLs.com
  • SSLmate.com

證書有很多類型,首先分爲三種認證級別。

  • 域名認證(Domain Validation):最低級別認證,可以確認申請人擁有這個域名。對於這種證書,瀏覽器會在地址欄顯示一把鎖。
  • 公司認證(Company Validation):確認域名所有人是哪一家公司,證書裏面會包含公司信息。
  • 擴展認證(Extended Validation):最高級別的認證,瀏覽器地址欄會顯示公司名。

還分爲三種覆蓋範圍。

  • 單域名證書:只能用於單一域名,foo.com的證書不能用於www.foo.com
  • 通配符證書:可以用於某個域名及其所有一級子域名,比如*.foo.com的證書可以用於foo.com,也可以用於www.foo.com
  • 多域名證書:可以用於多個域名,比如foo.combar.com

認證級別越高、覆蓋範圍越廣的證書,價格越貴。還有一個免費證書的選擇。爲了推廣HTTPS協議,電子前哨基金會EFF成立了Let's Encrypt,提供免費證書(教程和工具)。

拿到證書以後,可以用SSL Certificate Check檢查一下,信息是否正確。

(2)安裝證書

證書可以放在/etc/ssl目錄(Linux 系統),然後根據你使用的Web服務器進行配置。

(3)修改鏈接(前端主要的工作都在此)

網頁加載的HTTP資源,要全部改成HTTPS鏈接。因爲加密網頁內如果有非加密的資源,瀏覽器是不會加載那些資源的。

<script src="http://foo.com/jquery.js"></script>

上面這行加載命令,有兩種改法:

<!-- 改法一 -->
<script src="https://foo.com/jquery.js"></script>

<!-- 改法二 -->
<script src="//foo.com/jquery.js"></script>

其中,改法二會根據當前網頁的協議,加載相同協議的外部資源,更靈活一些。

另外,如果頁面頭部用到了rel="canonical",也要改成HTTPS網址。

<link rel="canonical" href="https://foo.com/bar.html" />

(4)301重定向

下一步,修改Web服務器的配置文件,使用301重定向,將HTTP協議的訪問導向HTTPS協議。

server {
  listen 80;
  server_name domain.com www.domain.com;
  return 301 https://domain.com$request_uri;
}

HTTPS的七個誤解

(1)HTTPS無法緩存

許多人以爲,出於安全考慮,瀏覽器不會在本地保存HTTPS緩存。實際上,只要在HTTP頭中使用特定命令,HTTPS是可以緩存的。

(2)SSL證書很貴

如果你在網上搜一下,就會發現很多便宜的SSL證書,大概10美元一年,這和一個.com域名的年費差不多。而且事實上,還能找到免費的SSL證書。

(3)HTTPS站點必須有獨享的IP地址

每個IP地址只能安裝一張SSL證書,這是毫無疑問的。但是,如果你使用子域名通配符SSL證書(wildcard SSL certificate,價格大約是每年125美元),就能在一個IP地址上部署多個HTTPS子域名。

比如,https://www.httpwatch.comhttps://store.httpwatch.com,就共享同一個IP地址。

(4)轉移服務器時要購買新證書

IS的做法是生成一個可以轉移的.pfx文件,並加以密碼保護。將這個文件傳入其他服務器,將可以繼續使用原來的SSL證書了。

(5)HTTPS太慢

第一次打開網頁的時候,HTTPS協議會比HTTP協議慢一點,這是因爲讀取和驗證SSL證書的時間。

但是,一旦有效的HTTPS連接建立起來,再刷新網頁,兩種協議幾乎沒有區別。

(6)有了HTTPS,Cookie和查詢字符串就安全了

雖然無法直接從HTTPS數據中讀取Cookie和查詢字符串,但是你仍然需要使它們的值變得難以預測。

(7)只有註冊登錄頁,才需要HTTPS

這種想法很普遍。人們覺得,HTTPS可以保護用戶的密碼,此外就不需要了。在Twitter和Facebook上,劫持其他人的Session是非常容易的。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章