前言
作為一個有追求的程式設計師,瞭解行業發展趨勢和擴充自己的計算機知識儲備都是很有必要的,特別是一些計算機基礎方面的內容,就比如本篇文章要講的計算機網路方面的知識。本文將為大家詳細梳理一下 HTTPS 的實現原理。
近年來,隨著使用者和網際網路企業安全意識的提高和 HTTPS 成本的下降,HTTPS 已經越來越普及。很多網際網路巨頭也在力推 HTTPS,比如谷歌的 Chrome 瀏覽器在訪問 HTTP 網站時會在位址列顯示不安全的提醒,微信要求所有的小程式必須使用 HTTPS 傳輸協議,蘋果也要求所有在 App Store 上架的應用必須採用 HTTPS ,國內外的大部分主流網站也都已遷移至 HTTPS,可見 HTTPS 全面取代 HTTP 只是時間問題。
說了這麼多,究竟什麼是 HTTPS?它與 HTTP 相比有什麼優缺點?其底層實現原理又是怎樣的呢?下面就為你一一解答,先來看一下 HTTP 的弊端吧。
1、HTTP 的最大弊端——不安全
HTTP 之所以被 HTTPS 取代,最大的原因就是不安全,至於為什麼不安全,看了下面這張圖就一目瞭然了。
圖1. HTTP資料傳輸過程
由圖可見,HTTP 在傳輸資料的過程中,所有的資料都是明文傳輸,自然沒有安全性可言,特別是一些敏感資料,比如使用者密碼和信用卡資訊等,一旦被第三方獲取,後果不堪設想。這裡可能有人會說,我在前端頁面對敏感資料進行加密不就行了,比如 MD5 加鹽加密。這麼想就太簡單了。首先 MD5 並不是加密演算法,其全稱是 Message Digest Algorithm MD5,意為資訊摘要演算法,是一種不可逆的雜湊演算法,也就是說經過前端 MD5 處理過的資料在伺服器端是無法復原的。這裡以密碼舉例,前端把使用者密碼透過 MD5 進行處理,並把得到的雜湊值傳送給伺服器,伺服器由於無法復原密碼,就會直接用這個雜湊值處理使用者請求。所以第三方在獲取這個雜湊值後,可以繞過前端登入頁面直接訪問伺服器,造成安全問題。另外,MD5 演算法本身的安全性也存在缺陷,這裡就不展開談了。
總之 MD5,SHA-1 之類的雜湊演算法並不能讓 HTTP 變得更安全。要想讓 HTTP 更安全,只能使用真正的加密演算法,因為加密演算法可以用金鑰加密或還原資料,只要確保金鑰不被第三方獲取,那就能確保資料傳輸的安全了。而這正是 HTTPS 的解決方案,那下面就來了解一下加密演算法吧。
2、加密演算法
HTTPS 解決資料傳輸安全問題的方案就是使用加密演算法,具體來說是混合加密演算法,也就是對稱加密和非對稱加密的混合使用,這裡有必要先了解一下這兩種加密演算法的區別和優缺點。
2.1 對稱加密
對稱加密,顧名思義就是加密和解密都是使用同一個金鑰,常見的對稱加密演算法有 DES、3DES 和 AES 等,其優缺點如下:
- 優點:演算法公開、計算量小、加密速度快、加密效率高,適合加密比較大的資料。
-
缺點:
- 交易雙方需要使用相同的金鑰,也就無法避免金鑰的傳輸,而金鑰在傳輸過程中無法保證不被截獲,因此對稱加密的安全性得不到保證。
- 每對使用者每次使用對稱加密演算法時,都需要使用其他人不知道的惟一金鑰,這會使得發收信雙方所擁有的鑰匙數量急劇增長,金鑰管理成為雙方的負擔。對稱加密演算法在分散式網路系統上使用較為困難,主要是因為金鑰管理困難,使用成本較高。
本文不對具體的加密演算法做詳細介紹,有興趣的同學可以參考 對稱加密演算法詳解,如果直接將對稱加密演算法用在 HTTP 中,會是下面的效果:
圖2. 對稱加密資料傳輸過程
從圖中可以看出,被加密的資料在傳輸過程中是無規則的亂碼,即便被第三方截獲,在沒有金鑰的情況下也無法解密資料,也就保證了資料的安全。但是有一個致命的問題,那就是既然雙方要使用相同的金鑰,那就必然要在傳輸資料之前先由一方把金鑰傳給另一方,那麼在此過程中金鑰就很有可能被截獲,這樣一來加密的資料也會被輕鬆解密。那如何確保金鑰在傳輸過程中的安全呢?這就要用到非對稱加密了。
2.2 非對稱加密
非對稱加密,顧名思義,就是加密和解密需要使用兩個不同的金鑰:公鑰(public key)和私鑰(private key)。公鑰與私鑰是一對,如果用公鑰對資料進行加密,只有用對應的私鑰才能解密;如果用私鑰對資料進行加密,那麼只有用對應的公鑰才能解密。非對稱加密演算法實現機密資訊交換的基本過程是:甲方生成一對金鑰並將其中的一把作為公鑰對外公開;得到該公鑰的乙方使用公鑰對機密資訊進行加密後再傳送給甲方;甲方再用自己儲存的私鑰對加密後的資訊進行解密。如果對公鑰和私鑰不太理解,可以想象成一把鑰匙和一個鎖頭,只是全世界只有你一個人有這把鑰匙,你可以把鎖頭給別人,別人可以用這個鎖把重要的東西鎖起來,然後發給你,因為只有你一個人有這把鑰匙,所以只有你才能看到被這把鎖鎖起來的東西。常用的非對稱加密演算法是 RSA 演算法,想詳細瞭解的同學點這裡:RSA 演算法詳解一、RSA 演算法詳解二,其優缺點如下:
- 優點:演算法公開,加密和解密使用不同的鑰匙,私鑰不需要透過網路進行傳輸,安全性很高。
- 缺點:計算量比較大,加密和解密速度相比對稱加密慢很多。
由於非對稱加密的強安全性,可以用它完美解決對稱加密的金鑰洩露問題,效果圖如下:
圖3. 客戶端透過非對稱加密把金鑰 KEY 傳送給伺服器
在上述過程中,客戶端在拿到伺服器的公鑰後,會生成一個隨機碼 (用 KEY 表示,這個 KEY 就是後續雙方用於對稱加密的金鑰),然後客戶端使用公鑰把 KEY 加密後再傳送給伺服器,伺服器使用私鑰將其解密,這樣雙方就有了同一個金鑰 KEY,然後雙方再使用 KEY 進行對稱加密互動資料。在非對稱加密傳輸 KEY 的過程中,即便第三方獲取了公鑰和加密後的 KEY,在沒有私鑰的情況下也無法破解 KEY (私鑰存在伺服器,洩露風險極小),也就保證了接下來對稱加密的資料安全。而上面這個流程圖正是 HTTPS 的雛形,HTTPS 正好綜合了這兩種加密演算法的優點,不僅保證了通訊安全,還保證了資料傳輸效率。
3、HTTPS 原理詳解
先看一下維基百科對 HTTPS 的定義
Hypertext Transfer Protocol Secure (HTTPS) is an extension of the Hypertext Transfer Protocol (HTTP). It is used for secure communication over a computer network, and is widely used on the Internet. In HTTPS, the communication protocol is encrypted using Transport Layer Security (TLS) or, formerly, its predecessor, Secure Sockets Layer (SSL). The protocol is therefore also often referred to as HTTP over TLS, or HTTP over SSL.HTTPS (Hypertext Transfer Protocol Secure) 是基於 HTTP 的擴充套件,用於計算機網路的安全通訊,已經在網際網路得到廣泛應用。在 HTTPS 中,原有的 HTTP 協議會得到 TLS (安全傳輸層協議) 或其前輩 SSL (安全套接層) 的加密。因此 HTTPS 也常指 HTTP over TLS 或 HTTP over SSL。
可見HTTPS 並非獨立的通訊協議,而是對 HTTP 的擴充套件,保證了通訊安全,二者關係如下:
圖4. HTTP和HTTPS的關係
也就是說 HTTPS = HTTP + SSL / TLS。
接下來就是最重要的 HTTPS 原理解析了,老規矩先上圖。
圖5. HTTPS 加密、解密、驗證及資料傳輸過程
看上去眼花繚亂,不要怕,且聽我細細道來。HTTPS 的整個通訊過程可以分為兩大階段:證書驗證和資料傳輸階段,資料傳輸階段又可以分為非對稱加密和對稱加密兩個階段。具體流程按圖中的序號講解。
1.客戶端請求 HTTPS 網址,然後連線到 server 的 443 埠 (HTTPS 預設埠,類似於 HTTP 的80埠)。
2.採用 HTTPS 協議的伺服器必須要有一套數字 CA (Certification Authority)證書,證書是需要申請的,並由專門的數字證書認證機構(CA)透過非常嚴格的稽核之後頒發的電子證書 (當然了是要錢的,安全級別越高價格越貴)。頒發證書的同時會產生一個私鑰和公鑰。私鑰由服務端自己儲存,不可洩漏。公鑰則是附帶在證書的資訊中,可以公開的。證書本身也附帶一個證書電子簽名,這個簽名用來驗證證書的完整性和真實性,可以防止證書被篡改。
3.伺服器響應客戶端請求,將證書傳遞給客戶端,證書包含公鑰和大量其他資訊,比如證書頒發機構資訊,公司資訊和證書有效期等。Chrome 瀏覽器點選位址列的鎖標誌再點選證書就可以看到證書詳細資訊。
圖6. B站 CA 證書
4.客戶端解析證書並對其進行驗證。如果證書不是可信機構頒佈,或者證書中的域名與實際域名不一致,或者證書已經過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通訊。就像下面這樣:
圖7. 瀏覽器安全警告
如果證書沒有問題,客戶端就會從伺服器證書中取出伺服器的公鑰A。然後客戶端還會生成一個隨機碼 KEY,並使用公鑰A將其加密。
5.客戶端把加密後的隨機碼 KEY 傳送給伺服器,作為後面對稱加密的金鑰。
6.伺服器在收到隨機碼 KEY 之後會使用私鑰B將其解密。經過以上這些步驟,客戶端和伺服器終於建立了安全連線,完美解決了對稱加密的金鑰洩露問題,接下來就可以用對稱加密愉快地進行通訊了。
7.伺服器使用金鑰 (隨機碼 KEY)對資料進行對稱加密併傳送給客戶端,客戶端使用相同的金鑰 (隨機碼 KEY)解密資料。
8.雙方使用對稱加密愉快地傳輸所有資料。
好了,以上就是 HTTPS 的原理詳解了,如此精美的圖搭配這麼詳細的過程解析,你再搞不懂就說不過去了吧哈哈。
4、總結
再來總結一下 HTTPS 和 HTTP 的區別以及 HTTPS 的缺點吧:
HTTPS 和 HTTP 的區別:
- 最最重要的區別就是安全性,HTTP 明文傳輸,不對資料進行加密安全性較差。HTTPS (HTTP + SSL / TLS)的資料傳輸過程是加密的,安全性較好。
- 使用 HTTPS 協議需要申請 CA 證書,一般免費證書較少,因而需要一定費用。證書頒發機構如:Symantec、Comodo、DigiCert 和 GlobalSign 等。
- HTTP 頁面響應速度比 HTTPS 快,這個很好理解,由於加了一層安全層,建立連線的過程更復雜,也要交換更多的資料,難免影響速度。
- 由於 HTTPS 是建構在 SSL / TLS 之上的 HTTP 協議,所以,要比 HTTP 更耗費伺服器資源。
- HTTPS 和 HTTP 使用的是完全不同的連線方式,用的埠也不一樣,前者是 443,後者是 80。
HTTPS 的缺點:
- 在相同網路環境中,HTTPS 相比 HTTP 無論是響應時間還是耗電量都有大幅度上升。
- HTTPS 的安全是有範圍的,在駭客攻擊、伺服器劫持等情況下幾乎起不到作用。
- 在現有的證書機制下,中間人攻擊依然有可能發生。
- HTTPS 需要更多的伺服器資源,也會導致成本的升高。
顯然,HTTPS 相比 HTTP最大的不同就是多了一層 SSL (Secure Sockets Layer 安全套接層)或 TLS (Transport Layer Security 安全傳輸層協議)。有了這個安全層,就確保了網際網路上通訊雙方的通訊安全,那麼這個安全層是怎麼工作的,SSL / TLS 握手過程又是怎樣的呢?本文將對這些問題一一解答。
1、SSL / TLS 以及 SSL / TLS 握手的概念
SSL 和 TLS 協議可以為通訊雙方提供識別和認證通道,從而保證通訊的機密性和資料完整性。TLS 協議是從Netscape SSL 3.0協議演變而來的,不過這兩種協議並不相容,SSL 已經逐漸被 TLS 取代,所以下文就以 TLS 指代安全層。 TLS 握手是啟動 HTTPS 通訊的過程,類似於 TCP 建立連線時的三次握手。 在 TLS 握手的過程中,通訊雙方交換訊息以相互驗證,相互確認,並確立它們所要使用的加密演算法以及會話金鑰 (用於對稱加密的金鑰)。可以說,TLS 握手是 HTTPS 通訊的基礎部分。
2、TLS 握手過程中發生了什麼
我們已經知道 TLS 握手的目的是建立安全連線,那麼通訊雙方在這個過程中究竟幹了什麼呢?下面就是答案:
- 商定雙方通訊所使用的的 TLS 版本 (例如 TLS1.0, 1.2, 1.3等等);
- 確定雙方所要使用的密碼組合;
- 客戶端透過伺服器的公鑰和數字證書 (上篇文章已有介紹)上的數字簽名驗證服務端的身份;
- 生成會話金鑰,該金鑰將用於握手結束後的對稱加密。
3、TLS 握手詳細過程
下面來看 TLS 握手的詳細過程 (注:此圖與HTTPS詳解一中的 HTTPS 原理圖的流程大致相同,不同的是此圖把重點放在了TLS握手的相關概念上):
SSL / TLS 握手詳細過程
- "client hello"訊息:客戶端透過傳送"client hello"訊息向伺服器發起握手請求,該訊息包含了客戶端所支援的 TLS 版本和密碼組合以供伺服器進行選擇,還有一個"client random"隨機字串。
- "server hello"訊息:伺服器傳送"server hello"訊息對客戶端進行回應,該訊息包含了數字證書,伺服器選擇的密碼組合和"server random"隨機字串。
-
驗證:客戶端對伺服器發來的證書進行驗證,確保對方的合法身份,驗證過程可以細化為以下幾個步驟:
- 檢查數字簽名
- 驗證證書鏈 (這個概念下面會進行說明)
- 檢查證書的有效期
- 檢查證書的撤回狀態 (撤回代表證書已失效)
- "premaster secret"字串:客戶端向伺服器傳送另一個隨機字串"premaster secret (預主金鑰)",這個字串是經過伺服器的公鑰加密過的,只有對應的私鑰才能解密。
- 使用私鑰:伺服器使用私鑰解密"premaster secret"。
- 生成共享金鑰:客戶端和伺服器均使用 client random,server random 和 premaster secret,並透過相同的演算法生成相同的共享金鑰 KEY。
- 客戶端就緒:客戶端傳送經過共享金鑰 KEY加密過的"finished"訊號。
- 伺服器就緒:伺服器傳送經過共享金鑰 KEY加密過的"finished"訊號。
- 達成安全通訊:握手完成,雙方使用對稱加密進行安全通訊。
4、TLS 握手過程中的一些重要概念
-
數字證書 (digital certificate):在非對稱加密通訊過程中,伺服器需要將公鑰傳送給客戶端,在這一過程中,公鑰很可能會被第三方攔截並替換,然後這個第三方就可以冒充伺服器與客戶端進行通訊,這就是傳說中的“中間人攻擊”(man in the middle attack)。解決此問題的方法是透過受信任的第三方交換公鑰,具體做法就是伺服器不直接向客戶端傳送公鑰,而是要求受信任的第三方,也就是證書認證機構 (Certificate Authority, 簡稱 CA)將公鑰合併到數字證書中,然後伺服器會把公鑰連同證書一起傳送給客戶端,私鑰則由伺服器自己儲存以確保安全。數字證書一般包含以下內容:
- 證書所有者的公鑰
- 證書所有者的專有名稱
- 證書頒發機構的專有名稱
- 證書的有效起始日期
- 證書的過期日期
- 證書資料格式的版本號
- 序列號,這是證書頒發機構為該證書分配的唯一識別符號
... ...
-
數字簽名 (digital signature):這個概念很好理解,其實跟人的手寫簽名類似,是為了確保資料傳送者的合法身份,也可以確保資料內容未遭到篡改,保證資料完整性。與手寫簽名不同的是,數字簽名會隨著文字資料的變化而變化。具體到數字證書的應用場景,數字簽名的生成和驗證流程如下:
- 伺服器對證書內容進行資訊摘要計算 (常用演算法有 SHA-256等),得到摘要資訊,再用私鑰把摘要資訊加密,就得到了數字簽名
- 伺服器把數字證書連同數字簽名一起傳送給客戶端
- 客戶端用公鑰解密數字簽名,得到摘要資訊
- 客戶端用相同的資訊摘要演算法重新計算證書摘要資訊,然後對這兩個摘要資訊進行比對,如果相同,則說明證書未被篡改,否則證書驗證失敗
- 證書鏈 (certificate chain):證書鏈,也稱為證書路徑,是用於認證實體合法身份的證書列表,具體到 HTTPS 通訊中,就是為了驗證伺服器的合法身份。之所以使用證書鏈,是為了保證根證書 (root CA certificate)的安全,中間層可以看做根證書的代理,起到了緩衝的作用,如下圖所示,這裡還以 B 站證書為例:
證書鏈
證書鏈從根證書開始,並且證書鏈中的每一級證書所標識的實體都要為其下一級證書籤名,而根證書自身則由證書頒發機構簽名。客戶端在驗證證書鏈時,必須對鏈中所有證書的數字簽名進行驗證,直到達到根證書為止。
4.密碼規範和密碼組合 (CipherSpecs 和 CipherSuites):通訊雙方在安全連線中所使用的演算法必須符合密碼安全協議的規定,CipherSpecs 和 CipherSuites 正好定義了合法的密碼演算法組合。CipherSpecs 用於認證加密演算法和資訊摘要演算法的組合,通訊雙方必須同意這個密碼規範才能進行通訊。而 CipherSuites 則定義了 SSL / TLS 安全連線中所使用的加密演算法的組合,該組合包含三種不同的演算法:
- 握手期間所使用的的金鑰交換和認證演算法 (最常用的是 RSA 演算法)
- 加密演算法 (用於握手完成後的對稱加密,常用的有 AES、3DES等)
- 資訊摘要演算法 (常用的有 SHA-256、SHA-1 和 MD5 等)
4、總結
本文對 SSL / TLS 握手過程進行了詳細的解析,也對握手過程中的幾個重要概念進行了補充說明。想繼續深入瞭解的小夥伴可以去參考一下 CloudFlare 和 IBM 的官網,這兩個網站也是本文內容的主要來源。多逛逛英文網站,不僅可以漲姿勢,獲取權威資訊,還能順帶提升一波英語水平,一舉兩得,豈不美哉,希望小夥伴們也能儘快養成這樣的好習慣。HTTPS 詳解部分到此結束,咱們下篇文章再見。