帶你從零到一理解 HTTPS

前言

本文將逐步的來還原 HTTPS 的設計過程,理解從 HTTP 到 HTTPS 的轉變中,到底都發生了些什麼。html

HTTP 的缺陷

首先先來講說爲何須要 HTTPS, 也就是 HTTP 的主要不足是什麼算法

  • 通訊使用明文(不加密),內容可能會被竊聽
  • 不驗證通訊方的身份,所以有可能遭遇假裝
  • 沒法證實報文的完整性,因此有可能已遭篡改

通訊使用明文可能被竊聽

HTTP 自己不具有加密的功能,即 HTTP 報文使用明文(指未通過加密的報文)方式發送。shell

所謂互聯網,是由能連通到全世界的網絡組成的。不管世界哪一個角落的服務器在和客戶端通訊時,在此通訊線路上的某些網絡設備、光纜、計算機等都不多是我的的私有物,因此不排除某個環節中會遭到惡意窺視行爲。瀏覽器

好比使用免費的抓包工具 Wireshark, 就能夠獲取 HTTP 的請求和響應報文進行分析。安全

加密處理防止被竊聽

目前你們正在研究的如何防止竊聽保護信息的幾種對策中,最爲普及的就是加密技術。加密的對象爲如下服務器

通訊加密

HTTP 協議中沒有加密機制,但能夠經過和 SSL(Secure Socket Layer,安全套接層)或 TLS(Transport Layer Security,安全層傳輸協議)的組合使用,加密 HTTP 的通訊內容網絡

一般,HTTP 直接和 TCP 通訊。當使用 SSL 時,則演變成先和 SSL 通訊,再由 SSL 和 TCP 通訊了。用 SSL 創建安全通訊線路以後,就能夠在這條線路上進行 HTTP 通訊了。工具

SSL 是獨立於 HTTP 的協議,因此不光是 HTTP 協議,其餘運行在應用層的 SMTP 和 Telnet 等協議都可配合 SSL 協議使用。能夠說 SSL 是當今世界上應用最爲普遍的網絡安全技術。網站

內容的加密

因爲 HTTP 協議中沒有加密機制,那麼就對 HTTP 協議傳輸的內容自己加密。即把 HTTP 報文裏所含的內容進行加密處理。ui

在這種狀況下,客戶端須要對 HTTP 報文進行加密處理後再發送請求。

爲了作到有效的內容加密,前提是要求客戶端和服務器同時具有加密和解密機制。

不驗證通訊方的身份就可能遭遇假裝

在 HTTP 協議通訊時,因爲不存在確認通訊方的處理步驟,任何人均可以發起請求。另外,服務器只要接收到請求,無論對方是誰都會返回一個響應 (但也僅限於發送端的 IP 地址和端口號沒有被 Web 服務器設定限制訪問的前提下)

HTTP 協議的實現自己很是簡單,不管是誰發送過來的請求都會返回響應,所以不確認通訊方,會存在如下各類隱患

  • 沒法肯定請求發送至目標的 Web 服務器是不是按真實意圖返回響應的那臺服務器。有多是假裝的 Web 服務器
  • 沒法肯定響應返回到的客戶端是不是按真實意圖接收響應的那個客戶端。有多是假裝的客戶端
  • 沒法肯定正在通訊的對方是否具有訪問權限。由於某些 Web 服務器上保存着重要的信息,只想發給特定用戶通訊的權限
  • 即便是無心義的請求也會照單全收。沒法阻止海量請求下的 DoS 攻擊 (Denial of Service,拒絕服務攻擊)
使用證書驗證身份

雖然使用 HTTP 協議沒法肯定通訊方,但若是使用 SSL 則能夠。SSL 不只提供加密處理,並且還使用了一種被稱爲證書的手段,可用於肯定雙方身份

證書由值得信任的第三方機構頒發,用以證實服務器和客戶端是實際存在的。另外,僞造證書從技術角度來講是異常困難的一件事。因此只要可以確認通訊方(服務器或客戶端)持有的證書,便可判斷通訊方的真實意圖

經過使用證書,以證實通訊方就是意料中的服務器。這對使用者我的來說,也減小了我的信息泄露的危險性。

另外,客戶端持有證書便可完成我的身份的確認,也可用於對 Web 網站的認證環節。

從古到今,三角戀的關係一直都不被看好,可是在 HTTPS 的協議裏,客戶端,服務器和被信賴的第三方機構這三者的關係倒是奠基一切的基礎。

沒法證實報文完整性,可能已遭篡改

所謂完整性是指信息的準確度。若沒法證實其完整性,一般也就意味着沒法判斷信息是否準確

因爲 HTTP 協議沒法證實通訊的報文完整性,所以在請求或響應送 出以後直到對方接收以前的這段時間內,即便請求或響應的內容遭到篡改,也沒有辦法獲悉。

好比,從某個 Web 網站上下載內容,是沒法肯定客戶端下載的文件和服務器上存放的文件是否先後一致的。文件內容在傳輸途中可能已經被篡改成其餘的內容。即便內容真的已改變,做爲接收方的客戶端也是覺察不到的。

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

雖然 HTTP 協議中有肯定報文完整性的方法,但事實上並不便捷、可靠。其中經常使用的是 MD5 和 SHA-1 等散列值校驗的方法,以及用來確認文件的數 字簽名方法。

惋惜的是,用這些方法也依然沒法百分百保證確認結果正確。因 MD5 自己被改寫的話,用戶是沒有辦法意識到的。

爲了有效防止這些弊端,有必要使用 HTTPS。SSL 提供認證和加密處理及摘要功能。僅靠 HTTP 確保完整性是很是困難的,所以經過和其餘協議組合使用來實現這個目標。

HTTP+ 加密 + 認證 + 完整性保護 = HTTPS

HTTPS 並不是是應用層的一種新協議。只是 HTTP 通訊接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協議代替而已。

簡言之,所謂 HTTPS,其實就是身披 SSL 協議這層外殼的 HTTP

加密方法

在對 SSL 進行講解以前,咱們先來了解一下加密方法。

加密方法只是解決方案,咱們首先要作的是理解咱們的問題域——什麼是安全?

A 與 B 通訊的內容,有且只有 A 和 B 有能力看到通訊的真正內容

好,問題域已經定義好了(現實中固然不止這一種定義)。對於解決方案,很容易就想到了對消息進行加密。

共享密鑰方式加密(對稱密鑰加密)

加密和解密同用一個密鑰的方式稱爲共享密鑰加密(Common key crypto system),也被叫作對稱密鑰加密。

只要這個密鑰不公開給第三者,同時密鑰足夠安全,咱們就解決了咱們一開始所定問題域了。由於世界上有且只有圖上的客戶端與服務器知道如何加密和解密他們之間的消息。

可是在實際的互聯網環境下 Web 服務器的通訊模型沒有這麼簡單,由於若是服務器端對全部的客戶端通訊都使用一樣的對稱加密算法,無異於沒有加密。因此實際中 Web 服務器與每一個客戶端使用不一樣的對稱加密算法

以共享密鑰方式加密(對稱密鑰加密)時必須將密鑰也發給對方。那麼就會產生一個新的問題,究竟怎樣才能安全地轉交?

在互聯網上轉發密鑰時,若是通訊被監聽那麼密鑰就可會落入攻擊者之 手,同時也就失去了加密的意義。另外還得設法安全地保管接收到的密鑰。

發送密鑰就有被竊聽的風險,但不發送,對方就不能解密。再說,密鑰若可以安全發送,那數據也應該能安全送達

公開密鑰加密(非對稱加密)

密碼學領域中,有一種稱爲「非對稱加密」的加密算法,特色是私鑰加密後的密文,只要是公鑰,均可以解密,可是公鑰加密後的密文,只有私鑰能夠解密。私鑰只有一我的有,而公鑰能夠發給全部的人。

使用公開密鑰加密方式,發送密文的一方使用對方的公開密鑰進行加密處理,對方收到被加密的信息後,再使用本身的私有密鑰進行解密。利用這種方式,不須要發送用來解密的私有密鑰,也沒必要擔憂密鑰被攻擊者竊聽而盜走。

另外,要想根據密文和公開密鑰,恢復到信息原文是異常困難的,由於解密過程就是在對離散對數進行求值,這並不是垂手可得就能辦到。退一步講,若是能對一個很是大的整數作到快速地因式分解,那麼密碼破解仍是存在但願的。但就目前的技術來看是不太現實的。

HTTPS 加密機制

若密鑰可以實現安全交換,那麼有可能會考慮僅使用公開密鑰加密來通訊。可是公開密鑰加密與共享密鑰加密相比,其處理速度要慢。

因此應充分利用二者各自的優點,將多種方法組合起來用於通訊。在交換密鑰環節使用公開密鑰加密方式,以後的創建通訊交換報文階段則使用共享密 鑰加密方式。

HTTPS 採用共享密鑰加密和公開密鑰加密二者並用的混合加密機制

公開密鑰加密處理起來比共享密鑰加密方式更爲複雜,所以若在通訊時使用公開密鑰加密方式,效率就很低

證實公開密鑰正確性的證書

細心的人可能已經注意到了若是使用公開密鑰加密,客戶端必須須要一開始就持有公鑰,要不無法開展加密行爲啊,因此須要服務器端將公鑰發送給每個客戶端。

遺憾的是,公開密鑰加密方式仍是存在一些問題的。那就是沒法證實公開密鑰自己就是貨真價實的公開密鑰。好比,正準備和某臺服務器創建公開密鑰加密方式下的通訊時,如何證實收到的公開密鑰就是本來預想的那臺服務器發行的公開密鑰。既若是服務器端發送公鑰給客戶端時,被中間人調包了,怎麼辦?

爲了解決上述問題,可使用由數字證書認證機構(CA,Certificate Authority)和其相關機關頒發的公開密鑰證書。

數字證書認證機構處於客戶端與服務器雙方均可信賴的第三方機構的立場上。服務器會將這份由數字證書認證機構頒發的公鑰證書發送給客戶端,以進行公開密鑰加密方式通訊。公鑰證書也可叫作數字證書或直接稱爲證書。

接到證書的客戶端可以使用數字證書認證機構的公開密鑰,對那張證書上的數字簽名進行驗證,一旦驗證經過,客戶端即可明確兩件事:

  • 認證服務器的公開密鑰的是真實有效的數字證書認證機構
  • 服務器的公開密鑰是值得信賴的

此處認證機關的公開密鑰必須安全地轉交給客戶端。使用通訊方式時,如何安全轉交是一件很困難的事,所以,多數瀏覽器開發商發佈版本時,會事先在內部植入經常使用認證機關的公開密鑰

到這裏可能會感受 HTTPS 的通訊過程結束了,可是還遺漏了一個場景:

第三方機構不可能只給你一家公司製做證書,它也可能會給中間人這樣有壞心思的公司發放證書。這樣的,中間人就有機會對你的證書進行調包,客戶端在這種狀況下是沒法分辨出是接收的是你的證書,仍是中間人的。由於不論中間人,仍是你的證書,都能使用第三方機構的公鑰進行解密。如圖

那客戶端是如何來驗證證書的呢? 答案是證書自己就已經告訴客戶端怎麼驗證證書的真僞。

證書上寫着如何根據證書的內容生成證書編號。客戶端拿到證書後根據證書上的方法本身生成一個證書編號,若是生成的證書編號與證書上的證書編號相同,那麼說明這個證書是真實的。

同時,爲避免證書編號自己又被調包,因此使用第三方的私鑰進行加密

證書的製做如圖所示

當客戶端拿到證書後,開始對證書中的內容進行驗證,若是客戶端計算出來的證書編號與證書中的證書編號相同,則驗證經過:

以上即爲 HTTPS 通訊的所有過程

思路整理

爲了更好地理解 HTTPS,咱們來整理一下 HTTPS 的通訊步驟

  1. 客戶端經過發送 Client Hello 報文開始 SSL 通訊。報文中包含客戶端支持的 SSL 的指定版本、加密組件(Cipher Suite)列表(所使用的加密算法及密鑰長度等)
  2. 服務器可進行 SSL 通訊時,會以 Server Hello 報文做爲應答。和客戶端同樣,在報文中包含 SSL 版本以及加密組件。服務器的加密組件內容是從接收 到的客戶端加密組件內篩選出來的。
  3. 以後服務器發送 Certificate 報文。報文中包含公開密鑰證書。
  4. 最後服務器發送 Server Hello Done 報文通知客戶端,最初階段的 SSL 握手協商部分結束。
  5. SSL 第一次握手結束以後,客戶端以 Client Key Exchange 報文做爲迴應。報文中包含通訊加密中使用的一種被稱爲 Pre-master secret 的隨機密碼串。該 報文已用步驟 3 中的公開密鑰進行加密。
  6. 接着客戶端繼續發送 Change Cipher Spec 報文。該報文會提示服務器,在此報文以後的通訊會採用 Pre-master secret 密鑰加密。
  7. 客戶端發送 Finished 報文。該報文包含鏈接至今所有報文的總體校驗值。此次握手協商是否可以成功,要以服務器是否可以正確解密該報文做爲斷定標準。
  8. 服務器一樣發送 Change Cipher Spec 報文。
  9. 服務器一樣發送 Finished 報文。
  10. 服務器和客戶端的 Finished 報文交換完畢以後,SSL 鏈接就算創建完成。固然,通訊會受到 SSL 的保護。今後處開始進行應用層協議的通訊,即發 送 HTTP 請求。
  11. 應用層協議通訊,即發送 HTTP 響應。
  12. 最後由客戶端斷開鏈接。斷開鏈接時,發送 close_notify 報文。

以上作了一些省略,這步以後再發送 TCP FIN 報文來關閉與 TCP 的通訊。

在以上流程中,應用層發送數據時會附加一種叫作 MAC(Message Authentication Code)的報文摘要。MAC 可以查知報文是否遭到篡改,從而保護報文的完整性。

HTTPS 缺陷

HTTPS 也存在一些問題,那就是當使用 SSL 時,它的處理速度會變慢。

因爲 HTTPS 還須要作服務器、客戶端雙方加密及解密處理,所以會消耗 CPU 和內存等硬件的資源
和 HTTP 通訊相比,SSL 通訊部分消耗網絡資源。而 SSL 通訊部分,又由於要對通訊進行處理,因此時間上又延長了

相關技術文章推薦

想了解如何給本身的網站啓用 HTTPS 能夠參考左耳朵耗子如何免費的讓網站啓用HTTPS

Android HTTPS 相關的能夠參考鴻洋的Android HTTPS 相關徹底解析 當 OKHttp 遇到 Https

參考

相關文章
相關標籤/搜索