跳到主要內容
黯羽輕揚每天積累一點點

HTTP 學習筆記 2_HTTPS

免費2015-05-30#HTTP#http入门#https#http与https#数字证书#http的缺陷#https通信具体过程

本文細緻地介紹 HTTPS,包括從 HTTP 到 HTTPS(HTTP 的缺陷)、HTTP 的本質、數字證書、加密方式、HTTPS 通訊具體過程等等

##一.HTTP

HTTPS 的出現是為了彌補 HTTP 的缺點:

  1. 通訊內容可能被竊聽

HTTP 使用明文通訊(不加密),內容很容易被竊聽,HTTP 本身不具備加密的功能,無法對通訊內容進行加密

不加密其實本來不是什麼大問題,但 TCP/IP 的工作機制致使整個通訊線路上的任意節點都能拿到報文,而且 Internet 中的任意一個節點都有可能成為中轉站,所以加密變得要緊了

加密不能阻止竊聽,竊聽者還是可以輕易拿走(加密過的)報文,但加密能讓報文失去價值(只要保證在一定時間內竊聽者無法解密就可以了)

  1. 身份可能遭偽裝

HTTP 協議沒有身份驗證機制,不會對通訊雙方進行確認,所以可能存在「假客戶端」、「假伺服器」。此外,DoS(Denial of Service)攻擊的存在也是因為 HTTP 沒有身份認證機制

由值得信任的第三方機構提供數字證書即可,證書既可以用來表明伺服器是「真伺服器」也能用來表明客戶端是「真客戶端」,只需要分別持有各自的證書

證書這麼好用,卻沒有普及,是因為第三方機構提供的證書是收費的(每張幾千到十幾萬 RMB 不等)。服務端好說,一張就好,但海量的客戶端證書就很昂貴了,一般應用無力支撐,所以只有網銀之類的應用需要安裝客戶端證書

P.S.至於證書是什麼,具體工作機制是什麼,下面會有詳細解釋,此外,還有不需要藉助第三方的「自簽名」,長遠來算很划算,但一般企業也玩不起

  1. 通訊內容可能被篡改

HTTP 無法證明報文完整性,不能確定報文在路上有沒有被攔截篡改,所以存在 MITM(Man-in-the-Middle,中間人)攻擊

現有的防篡改方法有 MD5、SHA-1 等散列值校驗以及用 PGP(Pretty Good Privacy,完美隱私)建立檔案的數字簽名等,都不好用,因為必須由客戶端使用者自行檢查篡改是否發生,瀏覽器無法自動完成,很不方便。而且,即便這樣做了,還是無法 100% 避免通訊內容被篡改,因為 PGP 和 MD5 本身也可能被改寫

##二。數字證書與混合加密

###1.混合加密

理解 HTTPS 前有必要先理解數字證書是什麼東西,而在這之前應該知道 3 種加密方式:

  • 對稱加密(共享金鑰加密):最簡單的加密方式,通訊雙方持有相同的金鑰

傳送方用金鑰加密後把密文傳送給接收方,接收方拿到密文後用同樣的金鑰進行解密得到明文,反之亦然

缺點:金鑰無法安全交給對方(在網路通訊中,資訊安全只能通過加密來保證,如果能把金鑰安全送達,那就意味著其它資訊也能安全送達了)

  • 非對稱加密(公開金鑰加密):金鑰成對使用,分為公鑰和私鑰(公鑰是公開的,私鑰不公開)

公開公鑰,傳送方用公鑰加密,接收方拿到密文後用私鑰進行解密得到明文,反向通訊時傳送方用私鑰加密,接收方用公鑰解密即可

缺點:與對稱加密方式相比,非對稱方式加密解密過程有更大的開銷(要保證用密文 + 公鑰無法推算出私鑰,就需要複雜演算法的支援)

  • 混合加密(綜合以上兩種方式):用非對稱方式傳遞共享金鑰,然後用對稱方式通訊

對稱方式開銷小,最大的問題是無法保證金鑰被安全送達,而非對稱方式恰好能夠解決金鑰共享的問題,所以有了混合加密

先用非對稱方式傳遞共享金鑰,保證了金鑰能被安全送達,再用對稱加密方式通訊,避免了使用非對稱方式通訊的開銷,完美了

HTTPS 採用的就是混合加密方式

###2.數字證書

數字證書其實是被加密過的公鑰,這份證書能夠同時證明證書主人(數字證書認證機構)和公鑰主人(伺服器/客戶端)的身份。具體原理如下:

背景:服務端 S 決定對通訊進行加密,以保證客戶線上辦理業務時的資訊安全

  1. 把 S 的公鑰發布出去(告訴客戶端 C)

怎麼發布是個問題,因為 C 收到公鑰後不能確定公鑰是不是真的(無法證明 S 的身份),萬一是別人惡意發布的就麻煩了。

如果 C 只收到 1 個假公鑰,可以用該公鑰對請求進行加密,然後 S 發現無法解密後拒絕請求就好了,只用多發一個請求就能解決問題。但如果 C 收到 100 個假公鑰呢,繼續一個一個驗證嗎?

當然不行,這時就需要藉助第三方數字證書認證機構了

  1. S 請數字證書認證機構 CA 幫忙發布公鑰,以證明這個公鑰是真的(證明 S 的身份)

CA 收了 S 給的小費後,用自己的私鑰對公鑰進行加密,得到的這個密文就是數字證書。再把這個證書交給 S,說以後只要把證書給 C,C 就知道你是真的了(P.S.其實「證書」非常貼切,S 為了證明自己的身份,去找 CA 辦身份證,CA 給蓋了個紅戳,這就是「證書」)

等等,為什麼 C 一看證書就知道是不是真的?萬一證書是假的呢?怎麼證明證書的有效性?

為了避免這樣無休止的證明下去,瀏覽器中內建了 CA 的公鑰,C 一拿到 S 給的證書,馬上取出 CA 的公鑰對證書進行解密,如果證書是真的,C 就能拿到 S 的公鑰(證書是用 CA 的私鑰對 S 的公鑰進行加密的產物,解密當然能得到 S 的公鑰),這不僅證明了 S 的身份,還證明了 CA 的身份

注意,瀏覽器內建 CA 公鑰是無償的,瀏覽器為了適應市場需求必須把各大 CA 的公鑰內建到瀏覽器中,而 CA 不用給瀏覽器供應商小費,為什麼一直強調錢?

為了說明證書是收費的,而且不便宜,前面提到了:

>  證書這麼好用,卻沒有普及,是因為第三方機構提供的證書是收費的(每張幾千到十幾萬 RMB 不等)。服務端好說,一張就好,但海量的客戶端證書就很昂貴了,一般應用無力支撐,所以只有網銀之類的應用需要安裝客戶端證書

3. C 拿到 S 的公鑰後,加密傳送共享金鑰(Pre-master secret 隨機密碼串)

  1. S 用私鑰對收到的共享金鑰進行解密,得到共享金鑰,然後開始快速安全的通訊

上面的例子是服務端證書,用來證明服務端的身份。同理,也可以有用來證明客戶端身份的客戶端證書,比如網銀的 U 盾

因為證書價格不菲,所以也只有網銀之類的東西有客戶端證書

###3.自簽名

知名 CA 機構的證書是比較昂貴的,所以一些企業決定自己搞證書(自己當 CA),這就是為什麼有時候瀏覽網頁時候瀏覽器會彈個視窗提示該站點的證書不可信,是否繼續訪問……其實是因為瀏覽器沒有內建該站點的公鑰,結果就是瀏覽器看到了證書,卻無法證明證書的真假

所以自簽名沒什麼意義,並不能提升通訊安全性,除非自己當 CA 已經做大成了知名 CA,公鑰被瀏覽器收藏了才算

自簽名的好處是證書很廉價,因為只要具備了生產條件,可以產出無限多個證書,隨便發。

但自己當 CA 不是那麼簡單,CA 要求具備非常可靠的安全防護條件,所以知名 CA 對證書收費也是合理的,用來維護證書頒佈系統的安全

##三.HTTPS

###1.HTTPS 是什麼?

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

      = HTTP + (SSL + TLS 實現的)加密 + (數字證書實現的)認證 + (數字證書實現的)完整性保護
      
HTTP = TCP + IP

HTTPS = SSL + TCP + IP

P.S.TLS 是以 SSL 為原型開發的協議,有時候統一稱為 SSL,所以最後一個等式中沒有 TLS

注意:

  1. HTTPS 比 HTTP 慢 2 到 100 倍

一方面 SSL 通訊本身慢(SSL 的傳輸處理);另一方面 SSL 開銷大,處理速度慢

沒有根本性的解決辦法,可以用 SSL 加速器這樣的(專用伺服器)硬體來提升 SSL 處理速度

  1. HTTPS 並不是一直進行加密通訊

只有在傳輸敏感資訊時才加密(用 HTTPS),其它時候仍然用 HTTP,可以提升通訊速率並減少開銷

###2.加密方式

  • 通訊的加密

HTTP 沒有加密機制,所以引入 SSL(Secure Sockets Layer)和 TLS(Transport Layer Security)實現對通訊的加密

用 SSL 建立安全通訊線路之後,在這條線路上進行 HTTP 通訊,這樣的方式被稱為 HTTPS(HTTP Secure,超文字傳輸安全協議)或者 HTTP over SSL

  • 內容的加密

對報文主體進行加密,當然,這需要客戶端、伺服器的雙向配合(都要支援加密/解密功能)

而且只對內容加密並不安全,因為報文首部沒有加密,HTTP 首部注入攻擊可破之

###3.身份認證方式

  • BASIC 認證

服務端返回 401 響應要求身份認證,客戶端把使用者名稱和密碼用 Base64 編碼後傳送給服務端,服務端根據這個字串進行身份驗證,成功返回 200,否則繼續 401

Base64 編碼並不是加密,與明文傳輸沒什麼區別,HTTP 傳輸極不安全,所以不常用

  • DIGEST 認證

既然 BASIC 認證用 Base64 編碼傳輸密碼不安全,那麼就對密碼進行簡單加密(對密碼做 MD5 運算)

能防止竊聽,但無法防止身份偽裝,也不常用

  • SSL 客戶端認證

用證書可以防止身份偽裝,客戶端把客戶端證書傳送給服務端,服務端取出客戶端的公鑰,然後開始 HTTPS 通訊

但客戶端證書也是收費的,所以也不常用

  • 基於表單的認證

最常用的是基於表單的認證,安全性取決於 Web 應用程式

一般會用到 MD5 + salt(加鹽的 MD5),這裡有必要說明一下:

salt 其實是服務端生成的隨即字串,保存在伺服器資料庫裡

新使用者註冊時生成一個與使用者 ID 對應的 salt 串,然後把 salt 串與使用者的明文密碼進行拼接,對拼接結果做 MD5,結果作為使用者表裡該使用者的密碼串

登入時查表取出使用者對應的 salt,與明文密碼串拼接得到密碼串,再查使用者表取出該使用者的密碼與之對比,驗證身份

加鹽其實是為了方式查表破解 MD5,不加鹽的 MD5 用彩虹表很快就能查表破解,加鹽後就減少了密碼特徵(使用者表裡明文密碼相同的使用者的密碼串不同)

關於 MD5 + salt 有一篇非常好的文章,請查看 烏雲:加鹽 hash 儲存密碼的正確方式

##四.HTTPS 通訊過程

  1. 客戶端通過傳送 Client Hello 報文開始 SSL 通訊

報文中包含客戶端支援的 SSL 的指定版本、加密元件(Cipher Suite)列表(支援的加密演算法及金鑰長度等等)

  1. 服務端可進行 SSL 通訊時,以 Server Hello 報文作為應答

和客戶端一樣,在報文中包含 SSL 版本以及幾碼元件。服務端的加密元件內容是從接收到的客戶端加密元件內篩選出來的

  1. 服務端傳送 Certificate 報文

報文中包含公開金鑰證書

  1. 服務端傳送 Server Hello Done 報文通知客戶端

最初階段的 SSL 握手協商部分結束

  1. SSL 第一次握手結束之後,客戶端以 Client Key Exchange 報文作為回應

報文中包含通訊加密中使用的一種被稱為 Pre-master secret 的隨機密碼串。該報文已用步驟 3 中的公開金鑰進行加密

  1. 客戶端繼續傳送 Change Cipher Spec 報文

該報文提示服務端,在此報文之後的通訊會採用 Pre-master secret 金鑰加密

  1. 客戶端傳送 Finished 報文

該報文包含連線至今全部報文的整體校驗值,這次握手協商是否能夠成功,要以服務端是否能夠正確解密該報文作為判定標準

  1. 服務端同樣傳送 Change Cipher Spec 報文

  2. 服務端同樣傳送 Finished 報文

  3. 服務端和客戶端的 Finished 報文交換完畢後,SSL 連線算建立完成

當然,通訊會受到 SSL 保護,從此處開始進行應用層協議的通訊,即傳送 HTTP 請求

  1. 應用層協議通訊

傳送 HTTP 請求/響應,會附加 MAC(Message Authentication Code)報文摘要,檢查 MAC 能夠得知報文是否被篡改,以保護報文的完整性

  1. 最後由客戶端斷開連線

傳送 close_notify 報文

  1. 斷開 TCP 連線

傳送 TCP FIN 報文關閉 TCP 通訊

###參考資料

  • 《圖解 HTTP》

評論

暫無評論,快來發表你的看法吧

提交評論