超文本傳輸協議HTTP協議被用於在Web瀏覽器和網站服務器之間傳遞信息,HTTP協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此,HTTP協議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。
為了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文本傳輸協議HTTPS,為了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,並為瀏覽器和服務器之間的通信加密。
一、HTTP和HTTPS的基本概念
HTTP:是互聯網上應用最為廣泛的一種網絡協議,是一個客戶端和服務器端請求和應答的標准(TCP),用於從WWW服務器傳輸超文本到本地瀏覽器的傳輸協議,它可以使瀏覽器更加高效,使網絡傳輸減少。
HTTPS:是以安全為目標的HTTP通道,簡單講是HTTP的安全版,即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。
HTTPS協議的主要作用可以分為兩種:一種是建立一個信息安全通道,來保證數據傳輸的安全;另一種就是確認網站的真實性。
二、HTTP與HTTPS有什么區別?
HTTP協議傳輸的數據都是未加密的,也就是明文的,因此使用HTTP協議傳輸隱私信息非常不安全,為了保證這些隱私數據能加密傳輸,於是網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的數據進行加密,從而就誕生了HTTPS。簡單來說,HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全。
HTTPS和HTTP的區別主要如下:
1、https協議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。
三、HTTPS的工作原理
我們都知道HTTPS能夠加密信息,以免敏感信息被第三方獲取,所以很多銀行網站或電子郵箱等等安全級別較高的服務都會采用HTTPS協議。
客戶端在使用HTTPS方式與Web服務器通信時有以下幾個步驟,如圖所示。
(1)客戶使用https的URL訪問Web服務器,要求與Web服務器建立SSL連接。
(2)Web服務器收到客戶端請求后,會將網站的證書信息(證書中包含公鑰)傳送一份給客戶端。
(3)客戶端的瀏覽器與Web服務器開始協商SSL連接的安全等級,也就是信息加密的等級。
(4)客戶端的瀏覽器根據雙方同意的安全等級,建立會話密鑰,然后利用網站的公鑰將會話密鑰加密,並傳送給網站。
(5)Web服務器利用自己的私鑰解密出會話密鑰。
(6)Web服務器利用會話密鑰加密與客戶端之間的通信。
http原理通俗了解
我們先不了聊HTTP,HTTPS,我們先從一個聊天軟件說起,我們要實現A能發一個hello消息給B:
如果我們要實現這個聊天軟件,本文只考慮安全性問題,要實現
A發給B的hello消息包,即使被中間人攔截到了,也無法得知消息的內容
如何做到真正的安全?
這個問題,很多人馬上就想到了各種加密算法,什么對稱加密、非對稱加密、DES、RSA、XX、噼里啪啦~
而我想說,加密算法只是解決方案,我們首先要做的是理解我們的問題域——什么是安全?
我個人的理解是:
A與B通信的內容,有且只有A和B有能力看到通信的真正內容
好,問題域已經定義好了(現實中當然不止這一種定義)。對於解決方案,很容易就想到了對消息進行加密。
題外話,但是只有這一種方法嗎?我看未必,說不定在將來會出現一種物質打破當前世界的通信假設,實現真正意義上的保密。
對於A與B這樣的簡單通信模型,我們很容易做出選擇:
這就是對稱加密算法,其中圖中的密鑰S同時扮演加密和解密的角色。具體細節不是本文范疇。
只要這個密鑰S不公開給第三者,同時密鑰S足夠安全,我們就解決了我們一開始所定問題域了。因為世界上有且只有A與B知道如何加密和解密他們之間的消息。
但是,在WWW環境下,我們的Web服務器的通信模型沒有這么簡單:
如果服務器端對所有的客戶端通信都使用同樣的對稱加密算法,無異於沒有加密。那怎么辦呢?即能使用對稱加密算法,又不公開密鑰?請讀者思考21秒鍾。😜
答案是:Web服務器與每個客戶端使用不同的對稱加密算法:
如何確定對稱加密算法
慢着,另一個問題來了,我們的服務器端怎么告訴客戶端該使用哪種對稱加密算法?
當然是通過協商。
但是,你協商的過程是沒有加密的,還是會被中間人攔截。那我們再對這個協商過程進行對稱加密就好了,那你對協商過程加密的加密還是沒有加密,怎么辦?再加密不就好了……好吧,進行雞生蛋蛋生雞的問題了。
如何對協商過程進行加密
新問題來了,如何對協商過程進行加密?密碼學領域中,有一種稱為“非對稱加密”的加密算法,特點是私鑰加密后的密文,只要是公鑰,都可以解密,但是公鑰加密后的密文,只有私鑰可以解密。私鑰只有一個人有,而公鑰可以發給所有的人。
雖然服務器端向A、B……的方向還是不安全的,但是至少A、B向服務器端方向是安全的。
好了,如何協商加密算法的問題,我們解決了:使用非對稱加密算法進行對稱加密算法協商過程。
這下,你明白為什么HTTPS同時需要對稱加密算法和非對稱加密算法了吧?
協商什么加密算法
要達到Web服務器針對每個客戶端使用不同的對稱加密算法,同時,我們也不能讓第三者知道這個對稱加密算法是什么,怎么辦?
使用隨機數,就是使用隨機數來生成對稱加密算法。這樣就可以做到服務器和客戶端每次交互都是新的加密算法、只有在交互的那一該才確定加密算法。
這下,你明白為什么HTTPS協議握手階段會有這么多的隨機數了吧。
如何得到公鑰?
細心的人可能已經注意到了如果使用非對稱加密算法,我們的客戶端A,B需要一開始就持有公鑰,要不沒法開展加密行為啊。
這下,我們又遇到新問題了,如何讓A、B客戶端安全地得到公鑰?
我能想到的方案只有這些:
方案1. 服務器端將公鑰發送給每一個客戶端
方案2. 服務器端將公鑰放到一個遠程服務器,客戶端可以請求得到
我們選擇方案1,因為方案2又多了一次請求,還要另外處理公鑰的放置問題。
公鑰被調包了怎么辦?又是一個雞生蛋蛋生雞問題?
但是方案1有個問題:如果服務器端發送公鑰給客戶端時,被中間人調包了,怎么辦?
我畫了張圖方便理解:
顯然,讓每個客戶端的每個瀏覽器默認保存所有網站的公鑰是不現實的。
使用第三方機構的公鑰解決雞生蛋蛋生雞問題
公鑰被調包的問題出現,是因為我們的客戶端無法分辨返回公鑰的人到底是中間人,還是真的服務器。這其實就是密碼學中提的身份驗證問題。
如果讓你來解決,你怎么解決?如果你了解過HTTPS,會知道使用數字證書來解決。但是你想過證書的本質是什么么?請放下你對HTTPS已有的知識,自己嘗試找到解決方案。
我是這樣解決的。既然服務器需要將公鑰傳給客戶端,這個過程本身是不安全,那么我們為什么不對這個過程本身再加密一次?可是,你是使用對稱加密,還是非對稱加密?這下好了,我感覺又進了雞生蛋蛋生雞問題了。
問題的難點是如果我們選擇直接將公鑰傳遞給客戶端的方案,我們始終無法解決公鑰傳遞被中間人調包的問題。
所以,我們不能直接將服務器的公鑰傳遞給客戶端,而是第三方機構使用它的私鑰對我們的公鑰進行加密后,再傳給客戶端。客戶端再使用第三方機構的公鑰進行解密。
下圖就是我們設計的第一版“數字證書”,證書中只有服務器交給第三方機構的公鑰,而且這個公鑰被第三方機構的私鑰加密了:
如果能解密,就說明這個公鑰沒有被中間人調包。因為如果中間人使用自己的私鑰加密后的東西傳給客戶端,客戶端是無法使用第三方的公鑰進行解密的。
話到此,我以為解決問題了。但是現實中HTTPS,還有一個數字簽名的概念,我沒法理解它的設計理由。
原來,我漏掉了一個場景:第三方機構不可能只給你一家公司制作證書,它也可能會給中間人這樣有壞心思的公司發放證書。這樣的,中間人就有機會對你的證書進行調包,客戶端在這種情況下是無法分辨出是接收的是你的證書,還是中間人的。因為不論中間人,還是你的證書,都能使用第三方機構的公鑰進行解密。像下面這樣:
第三方機構向多家公司頒發證書的情況:
客戶端能解密同一家第三機構頒發的所有證書:
最終導致其它持有同一家第三方機構證書的中間人可以進行調包:
數字簽名,解決同一機構頒發的不同證書被篡改問題
要解決這個問題,我們首先要想清楚一個問題,辨別同一機構下不同證書的這個職責,我們應該放在哪?
只能放到客戶端了。意思是,客戶端在拿到證書后,自己就有能力分辨證書是否被篡改了。如何才能有這個能力呢?
我們從現實中找靈感。比如你是HR,你手上拿到候選人的學歷證書,證書上寫了持證人,頒發機構,頒發時間等等,同時證書上,還寫有一個最重要的:證書編號!我們怎么鑒別這張證書是的真偽呢?只要拿着這個證書編號上相關機構去查,如果證書上的持證人與現實的這個候選人一致,同時證書編號也能對應上,那么就說明這個證書是真實的。
我們的客戶端能不能采用這個機制呢?像這樣:
可是,這個“第三方機構”到底是在哪呢?是一個遠端服務?不可能吧?如果是個遠端服務,整個交互都會慢了。所以,這個第三方機構的驗證功能只能放在客戶端的本地了。
客戶端本地怎么驗證證書呢?
客戶端本地怎么驗證證書呢?答案是證書本身就已經告訴客戶端怎么驗證證書的真偽。
也就是證書上寫着如何根據證書的內容生成證書編號。客戶端拿到證書后根據證書上的方法自己生成一個證書編號,如果生成的證書編號與證書上的證書編號相同,那么說明這個證書是真實的。
同時,為避免證書編號本身又被調包,所以使用第三方的私鑰進行加密。
這地方有些抽象,我們來個圖幫助理解:
證書的制作如圖所示。證書中的“編號生成方法MD5”就是告訴客戶端:你使用MD5對證書的內容求值就可以得到一個證書編號。
當客戶端拿到證書后,開始對證書中的內容進行驗證,如果客戶端計算出來的證書編號與證書中的證書編號相同,則驗證通過:
但是第三方機構的公鑰怎么跑到了客戶端的機器中呢?世界上這么多機器。
其實呢,現實中,瀏覽器和操作系統都會維護一個權威的第三方機構列表(包括它們的公鑰)。因為客戶端接收到的證書中會寫有頒發機構,客戶端就根據這個頒發機構的值在本地找相應的公鑰。
題外話:如果瀏覽器和操作系統這道防線被破了,就沒辦法。想想當年自己裝過的非常規XP系統,都害怕。
說到這里,想必大家已經知道上文所說的,證書就是HTTPS中數字證書,證書編號就是數字簽名,而第三方機構就是指數字證書簽發機構(CA)。
CA如何頒發數字證書給服務器端的?
當我聽到這個問題時,我誤以為,我們的SERVER需要發網絡請求到CA部門的服務器來拿這個證書。😭 到底是我理解能力問題,還是。。
其實,問題應該是CA如何頒發給我們的網站管理員,而我們的管理員又如何將這個數字證書放到我們的服務器上。
我們如何向CA申請呢?每個CA機構都大同小異,我在網上找了一個:
拿到證書后,我們就可以將證書配置到自己的服務器上了。那么如何配置?這是具體細節了,留給大家google了。
也許我們需要整理一下思路
我們通過推算的方式嘗試還原HTTPS的設計過程。這樣,我們也就明白了為什么HTTPS比HTTP多那么多次的交互,為什么HTTPS的性能會差,以及找到HTTPS的性能優化點。
而上面一大堆工作都是為了讓客戶端與服務器端安全地協商出一個對稱加密算法。這就是HTTPS中的SSL/TLS協議主要干的活。剩下的就是通信時雙方使用這個對稱加密算法進行加密解密。
以下是一張HTTPS協議的真實交互圖(從網上copy的,忘了從哪了,如果侵權麻煩告知):
能不能用一句話總結HTTPS?
答案是不能,因為HTTPS本身實在太復雜。但是我還是嘗試使用一段話來總結HTTPS:
HTTPS要使客戶端與服務器端的通信過程得到安全保證,必須使用的對稱加密算法,但是協商對稱加密算法的過程,需要使用非對稱加密算法來保證安全,然而直接使用非對稱加密的過程本身也不安全,會有中間人篡改公鑰的可能性,所以客戶端與服務器不直接使用公鑰,而是使用數字證書簽發機構頒發的證書來保證非對稱加密過程本身的安全。這樣通過這些機制協商出一個對稱加密算法,就此雙方使用該算法進行加密解密。從而解決了客戶端與服務器端之間的通信安全問題。
四、HTTPS的優點
盡管HTTPS並非絕對安全,掌握根證書的機構、掌握加密算法的組織同樣可以進行中間人形式的攻擊,但HTTPS仍是現行架構下最安全的解決方案,主要有以下幾個好處:
(1)使用HTTPS協議可認證用戶和服務器,確保數據發送到正確的客戶機和服務器;
(2)HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全,可防止數據在傳輸過程中不被竊取、改變,確保數據的完整性。
(3)HTTPS是現行架構下最安全的解決方案,雖然不是絕對安全,但它大幅增加了中間人攻擊的成本。
(4)谷歌曾在2014年8月份調整搜索引擎算法,並稱“比起同等HTTP網站,采用HTTPS加密的網站在搜索結果中的排名將會更高”。
五、HTTPS的缺點
雖然說HTTPS有很大的優勢,但其相對來說,還是存在不足之處的:
(1)HTTPS協議握手階段比較費時,會使頁面的加載時間延長近50%,增加10%到20%的耗電;
(2)HTTPS連接緩存不如HTTP高效,會增加數據開銷和功耗,甚至已有的安全措施也會因此而受到影響;
(3)SSL證書需要錢,功能越強大的證書費用越高,個人網站、小網站沒有必要一般不會用。
(4)SSL證書通常需要綁定IP,不能在同一IP上綁定多個域名,IPv4資源不可能支撐這個消耗。
(5)HTTPS協議的加密范圍也比較有限,在黑客攻擊、拒絕服務攻擊、服務器劫持等方面幾乎起不到什么作用。最關鍵的,SSL證書的信用鏈體系並不安全,特別是在某些國家可以控制CA根證書的情況下,中間人攻擊一樣可行。
六、http切換到HTTPS
如果需要將網站從http切換到https到底該如何實現呢?
這里需要將頁面中所有的鏈接,例如js,css,圖片等等鏈接都由http改為https。例如:http://www.baidu.com改為https://www.baidu.com
BTW,這里雖然將http切換為了https,還是建議保留http。所以我們在切換的時候可以做http和https的兼容,具體實現方式是,去掉頁面鏈接中的http頭部,這樣可以自動匹配http頭和https頭。例如:將http://www.baidu.com改為//www.baidu.com。然后當用戶從http的入口進入訪問頁面時,頁面就是http,如果用戶是從https的入口進入訪問頁面,頁面即使https的。
參考:https://www.cnblogs.com/wqhwe/p/5407468.html
https://www.cnblogs.com/zhangshitong/p/6478721.html