轉自 |?碼海
- HTTP 為什么不安全
- 安全通信的四大原則
- HTTPS 通信原理簡述
- 對稱加密
- 數字證書
- 非對稱加密
- 數字簽名
HTTP 為什么不安全
HTTP 由于是明文傳輸,主要存在三大風險
1、 竊聽風險
中間人可以獲取到通信內容,由于內容是明文,所以獲取明文后有安全風險
2、 篡改風險
中間人可以篡改報文內容后再發送給對方,風險極大
3、 冒充風險
比如你以為是在和某寶通信,但實際上是在和一個釣魚網站通信。
HTTPS 顯然是為了解決這三大風險而存在的,接下來我們看看 HTTPS 到底解決了什么問題。
安全通信的四大原則
看了上一節,不難猜到 HTTPS 就是為了解決上述三個風險而生的,一般我們認為安全的通信需要包括以下四個原則: 機密性、完整性,身份認證和不可否認
- 機密性:即對數據加密,解決了竊聽風險,因為即使被中間人竊聽,由于數據是加密的,他也拿不到明文
- 完整性:指數據在傳輸過程中沒有被篡改,不多不少,保持原樣,中途如果哪怕改了一個標點符號,接收方也能識別出來,從來判定接收報文不合法
- 身份認證:確認對方的真實身份,即證明「你媽是你媽」的問題,這樣就解決了冒充風險,用戶不用擔心訪問的是某寶結果卻在和釣魚網站通信的問題
- 不可否認: 即不可否認已發生的行為,比如小明向小紅借了 1000 元,但沒打借條,或者打了借條但沒有 簽名,就會造成小紅的資金損失
接下來我們一步步來看看 HTTPS 是如何實現以滿足以上四大安全通信原則的。
HTTPS 通信原理簡述
對稱加密:HTTPS 的最終加密形式
既然 HTTP 是明文傳輸的,那我們給報文加密不就行了,既然要加密,我們肯定需要通信雙方協商好密鑰吧,一種是通信雙方使用同一把密鑰,即對稱加密的方式來給報文進行加解密。
如圖示:使用對稱加密的通信雙方使用同一把密鑰進行加解密。
對稱加密具有加解密速度快,性能高的特點,也是 HTTPS 最終采用的加密形式,但是這里有一個關鍵問題,對稱加密的通信雙方要使用同一把密鑰,這個密鑰是如何協商出來的?如果通過報文的方式直接傳輸密鑰,之后的通信其實還是在裸奔,因為這個密鑰會被中間人截獲甚至替換掉,這樣中間人就可以用截獲的密鑰解密報文,甚至替換掉密鑰以達到篡改報文的目的。
有人說對這個密鑰加密不就完了,但對方如果要解密這個密鑰還是要傳加密密鑰給對方,依然還是會被中間人截獲的,這么看來直接傳輸密鑰無論怎樣都無法擺脫俄羅斯套娃的難題,是不可行的。
非對稱加密:解決單向對稱密鑰的傳輸問題
直接傳輸密鑰無論從哪一端傳從上節分析來看是不行了,這里我們再看另一種加密方式:非對稱加密。
非對稱加密即加解密雙方使用不同的密鑰,一把作為公鑰,可以公開的,一把作為私鑰,不能公開,公鑰加密的密文只有私鑰可以解密,私鑰加密的內容,也只有公鑰可以解密。
注:私鑰加密其實這個說法其實并不嚴謹,準確的說私鑰加密應該叫私鑰簽名,因為私密加密的信息公鑰是可以解密的,而公鑰是公開的,任何人都可以拿到,用公鑰解密叫做驗簽
這樣的話對于 server 來說,保管好私鑰,發布公鑰給其他 client, 其他 client 只要把對稱加密的密鑰加密傳給 server 即可,如此一來由于公鑰加密只有私鑰能解密,而私鑰只有 server 有,所以能保證 client 向 server 傳輸是安全的,server 解密后即可拿到對稱加密密鑰,這樣交換了密鑰之后就可以用對稱加密密鑰通信了。
但是問題又來了, server 怎么把公鑰安全地傳輸給 client 呢。如果直接傳公鑰,也會存在被中間人調包的風險。
數字證書,解決公鑰傳輸信任問題
如何解決公鑰傳輸問題呢,從現實生活中的場景找答案,員工入職時,企業一般會要求提供學歷證明,顯然不是什么阿貓阿狗的本本都可稱為學歷,這個學歷必須由第三方權威機構(Certificate Authority,簡稱 CA)即教育部頒發,同理,server 也可以向 CA 申請證書,在證書中附上公鑰,然后將證書傳給 client,證書由站點管理者向 CA 申請,申請的時候會提交 DNS 主機名等信息,CA 會根據這些信息生成證書
這樣當 client 拿到證書后,就可以獲得證書上的公鑰,再用此公鑰加密對稱加密密鑰傳給 server 即可,看起來確實很完美,不過在這里大家要考慮兩個問題
問題一、 如何驗證證書的真實性,如何防止證書被篡改
想象一下上文中我們提到的學歷,企業如何認定你提供的學歷證書是真是假呢,答案是用學歷編號,企業拿到證書后用學歷編號在學信網上一查就知道證書真偽了,學歷編號其實就是我們常說的數字簽名,可以防止證書造假。
回到 HTTPS 上,證書的數字簽名該如何產生的呢,一圖勝千言
步驟如下 1、 首先使用一些摘要算法(如 MD5)將證書明文(如證書序列號,DNS主機名等)生成摘要,然后再用第三方權威機構的私鑰對生成的摘要進行加密(簽名)
消息摘要是把任意長度的輸入揉和而產生長度固定的偽隨機輸入的算法,無論輸入的消息有多長,計算出來的消息摘要的長度總是固定的,一般來說,只要內容不同,產生的摘要必然不同(相同的概率可以認為接近于 0),所以可以驗證內容是否被篡改了。
為啥要先生成摘要再加密呢,不能直接加密?
因為使用非對稱加密是非常耗時的,如果把整個證書內容都加密生成簽名的話,客戶端驗驗簽也需要把簽名解密,證書明文較長,客戶端驗簽就需要很長的時間,而用摘要的話,會把內容很長的明文壓縮成小得多的定長字符串,客戶端驗簽的話就會快得多。
2、客戶端拿到證書后也用同樣的摘要算法對證書明文計算摘要,兩者一筆對就可以發現報文是否被篡改了,那為啥要用第三方權威機構(Certificate Authority,簡稱 CA)私鑰對摘要加密呢,因為摘要算法是公開的,中間人可以替換掉證書明文,再根據證書上的摘要算法計算出摘要后把證書上的摘要也給替換掉!這樣 client 拿到證書后計算摘要發現一樣,誤以為此證書是合法就中招了。所以必須要用 CA 的私鑰給摘要進行加密生成簽名,這樣的話 client 得用 CA 的公鑰來給簽名解密,拿到的才是未經篡改合法的摘要(私鑰簽名,公鑰才能解密)
server 將證書傳給 client 后,client 的驗簽過程如下
這樣的話,由于只有 CA 的公鑰才能解密簽名,如果客戶端收到一個假的證書,使用 CA 的公鑰是無法解密的,如果客戶端收到了真的證書,但證書上的內容被篡改了,摘要比對不成功的話,客戶端也會認定此證書非法。
細心的你一定發現了問題,CA 公鑰如何安全地傳輸到 client ?如果還是從 server 傳輸到 client,依然無法解決公鑰被調包的風險,實際上此公鑰是存在于 CA 證書上,而此證書(也稱 Root CA 證書)被操作系統信任,內置在操作系統上的,無需傳輸,如果用的是 ?Mac 的同學,可以打開 keychain 查看一下,可以看到很多內置的被信任的證書。
server 傳輸 CA 頒發的證書,客戶中收到證書后使用內置 CA 證書中的公鑰來解密簽名,驗簽即可,這樣的話就解決了公鑰傳輸過程中被調包的風險。
問題二、 如何防止證書被調包
實際上任何站點都可以向第三方權威機構申請證書,中間人也不例外。
正常站點和中間人都可以向 CA 申請證書,獲得認證的證書由于都是 CA 頒發的,所以都是合法的,那么此時中間人是否可以在傳輸過程中將正常站點發給 client 的證書替換成自己的證書呢,如下所示
答案是不行,因為客戶端除了通過驗簽的方式驗證證書是否合法之外,還需要驗證證書上的域名與自己的請求域名是否一致,中間人中途雖然可以替換自己向 CA 申請的合法證書,但此證書中的域名與 client 請求的域名不一致,client 會認定為不通過!
但是上面的證書調包給了我們一種思路,什么思路?大家想想, ?HTTPS 既然是加密的, charles 這些「中間人」為啥能抓到明文的包呢,其實就是用了證書調包這一手法,想想看,在用 charles 抓 HTTPS 的包之前我們先要做什么,當然是安裝 charles 的證書
這個證書里有 charles 的公鑰,這樣的話 charles 就可以將 server 傳給 client 的證書調包成自己的證書,client 拿到后就可以用你安裝的 charles ?證書來驗簽等,驗證通過之后就會用 charles 證書中的公鑰來加密對稱密鑰了,整個流程如下
由此可知,charles 這些中間人能抓取 HTTPS 包的前提是信任它們的 CA 證書,然后就可以通過替換證書的方式進行瞞天過海,所以我們千萬不要隨便信任第三方的證書,避免安全風險。
其它 HTTPS 相關問題
什么是雙向認證
以上的講述過程中,我們只是在 client 端驗證了 server 傳輸證書的合法性,但 server 如何驗證 client 的合法性,還是用證書,我們在網上進行轉賬等操作時,想想看是不是要先將銀行發給我們的 U 盾插到電腦上?其實也是因為 U 盾內置了證書,通信時將證書發給 server,server 驗證通過之后即可開始通信。
畫外音:身份認證只是 U 盾功能的一種,還有其他功能,比如加解密都是在 U 盾中執行,保證了密鑰不會出現在內存中
什么是證書信任鏈
前文說了,我們可以向 CA 申請證書,但全世界的頂級 CA(Root CA) 就那么幾個,每天都有很多人要向它申請證書,它也忙不過來啊,怎么辦呢,想想看在一個公司里如果大家都找 CEO 辦事,他是不是要瘋了,那他能怎么辦?授權,他會把權力交給 CTO,CFO 等,這樣你們只要找 CTO 之類的就行了,CTO 如果也忙不過來呢,繼續往下授權啊。
同樣的,既然頂級 CA 忙不過來,那它就向下一級,下下級 CA 授權即可,這樣我們就只要找一級/二級/三級 CA 申請證書即可。怎么證明這些證書被 Root CA 授權過了呢,小一點的 CA 可以讓大一點的 CA 來簽名認證,比如一級 CA 讓 Root CA 來簽名認證,二級 CA 讓一級 CA 來簽名認證,Root CA 沒有人給他簽名認證,只能自己證明自己了,這個證書就叫「自簽名證書」或者「根證書」,我們必須信任它,不然證書信任鏈是走不下去的(這個根證書前文我們提過,其實是內置在操作系統中的)
證書信任鏈現在我們看看如果站點申請的是二級 CA 頒發的證書,client 收到之后會如何驗證這個證書呢,實際上 service 傳了傳給二級 CA 的證書外,還會把證書信任鏈也一起傳給客戶端,這樣客戶端會按如下步驟進行驗證:
- 瀏覽器就使用信任的根證書(根公鑰)解析證書鏈的根證書得到一級證書的公鑰+摘要驗簽
- 拿一級證書的公鑰解密一級證書,拿到二級證書的公鑰和摘要驗簽
- 再然后拿二級證書的公鑰解密 server 傳過來的二級證書,得到服務器的公鑰和摘要驗簽,驗證過程就結束了
總結
相信大家看完本文應該對 HTTPS 的原理有了很清楚的認識了, HTTPS 無非就是 HTTP + SSL/TLS
而 SSL/TLS 的功能其實本質上是如何協商出安全的對稱加密密鑰以利用此密鑰進行后續通訊的過程,帶著這個疑問相信你不難理解數字證書和數字簽名這兩個讓人費解的含義,搞懂了這些也就明白了為啥 ?HTTPS 是加密的,charles 這些工具卻能抓包出明文來。
巨人的肩膀
https://juejin.cn/post/6844903958863937550
https://showme.codes/2017-02-20/understand-https/
極客時間,透視 HTTP 協議
https://zhuanlan.zhihu.com/p/67199487
------------ END------------
免責聲明:本文內容由21ic獲得授權后發布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯系我們,謝謝!