大家好,我是程式設計師徐公,加上實習,有五年中大廠經驗。自薦一下,可以關注我的微信公眾號程式設計師徐公
- 公眾號程式設計師徐公回覆黑馬,獲取 Android 學習視訊
- 公眾號程式設計師徐公回覆徐公666,獲取簡歷模板,教你如何優化簡歷,走進大廠
- 公眾號程式設計師徐公回覆面試,可以獲得面試常見演算法,劍指 offer 題解
- 公眾號程式設計師徐公回覆馬士兵,可以獲得馬士兵學習視訊一份
前言
轉眼間,2020 年已過去一大半了,2020 年很難,各企業裁員的訊息蠻多的,降職,不發年終獎等等。2020 年確實是艱難的一年。然而生活總是要繼續,時間不給你喪的機會!如果我們能堅持下來,不斷提高自己,說不定會有新的機會。
面試中,網路(http, https, tcp, udp), jvm, 類載入機制等這些基礎的知識點是高頻出現的,每個程式設計師都能說上好多。但不一定說到重點,以及理解背後的原理。
我在面試的過程中也經常被問到,於是總結記錄了下來。千萬不要小瞧這些基礎,有時候,你演算法,專案經驗都過了,但是基礎答得不太好。結果可能會通過,但這肯定會影響你的評級,這是特別吃虧的。所以,不如花點時間背一下,理解一下背後的原理。
舉一個簡單的例子, https 連線過程是怎樣的,使用了了哪種加密方式,可以抓包嗎,怎樣防止抓包,你是否能夠對答如下。
廢話不多說,開始進入正文。
背景
我們知道,http 通訊存在以下問題:
- 通訊使用明文可能會被竊聽
- 不驗證通訊方的身份可能遭遇偽裝
- 無法證明報文的完整型,可能已遭篡改
使用 https 可以解決資料安全問題,但是你真的理解 https 嗎?
當面試官連續對你發出靈魂追問的時候,你能對答如流嗎
- 什麼是 https,為什麼需要 https
- https 的連線過程
- https 的加密方式是怎樣的,對稱加密和非對稱加密,為什麼要這樣設計?內容傳輸為什麼要使用對稱機密
- https 是絕對安全的嗎
- https 可以抓包嗎
如果你能對答自如,恭喜你,https 你已經掌握得差不多了,足夠應付面試了。
什麼是 https
簡單來說, https 是 http + ssl,對 http 通訊內容進行加密,是HTTP的安全版,是使用TLS/SSL加密的HTTP協議
Https的作用:
- 內容加密 建立一個資訊保安通道,來保證資料傳輸的安全;
- 身份認證 確認網站的真實性
- 資料完整性 防止內容被第三方冒充或者篡改
什麼是SSL
SSL 由 Netscape 公司於1994年建立,它旨在通過Web建立安全的Internet通訊。它是一種標準協議,用於加密瀏覽器和伺服器之間的通訊。它允許通過Internet安全輕鬆地傳輸賬號密碼、銀行卡、手機號等私密資訊。
SSL證書就是遵守SSL協議,由受信任的CA機構頒發的數字證書。
SSL/TLS的工作原理:
需要理解SSL/TLS的工作原理,我們需要掌握加密演算法。加密演算法有兩種:對稱加密和非對稱加密:
對稱加密:通訊雙方使用相同的金鑰進行加密。特點是加密速度快,但是缺點是需要保護好金鑰,如果金鑰洩露的話,那麼加密就會被別人pojie。常見的對稱加密有AES,DES演算法。
非對稱加密:它需要生成兩個金鑰:公鑰(Public Key)和私鑰(Private Key)。
公鑰顧名思義是公開的,任何人都可以獲得,而私鑰是私人保管的。相信大多程式設計師已經對這種演算法很熟悉了:我們提交程式碼到github的時候,就可以使用SSH key:在本地生成私鑰和公鑰,私鑰放在本地.ssh目錄中,公鑰放在github網站上,這樣每次提交程式碼,不用麻煩的輸入使用者名稱和密碼了,github會根據網站上儲存的公鑰來識別我們的身份。
公鑰負責加密,私鑰負責解密;或者,私鑰負責加密,公鑰負責解密。這種加密演算法安全性更高,但是計算量相比對稱加密大很多,加密和解密都很慢。常見的非對稱演算法有RSA。
https 的連線過程
https 的連線過程大概分為兩個階段,證書驗證階段和資料傳輸階段
證書驗證階段
大概分為三個步驟
- 瀏覽器發起請求
- 伺服器接收到請求之後,會返回證書,包括公鑰
- 瀏覽器接收到證書之後,會檢驗證書是否合法,不合法的話,會彈出告警提示(怎樣驗證合法,下文會詳細解析,這裡先忽略)
資料傳輸階段
證書驗證合法之後
- 瀏覽器會生成一個隨機數,
- 使用公鑰進行加密,傳送給服務端
- 伺服器收到瀏覽器發來的值,使用私鑰進行解密
- 解析成功之後,使用對稱加密演算法進行加密,傳輸給客戶端
之後雙方通訊就使用第一步生成的隨機數進行加密通訊。
https 的加密方式是怎樣的,對稱加密和非對稱加密,為什麼要這樣設計
從上面我們可以知道,https 加密是採用對稱加密和非對稱機密一起結合的。
在證書驗證階段,使用非對稱加密。
在資料傳輸階段,使用對稱機密。
這樣設計有一個好處,能最大程度得兼顧安全效率。
在證書驗證階段,使用非對稱加密,需要公鑰和私鑰,假如瀏覽器的公鑰洩漏了,我們還是能夠確保隨機數的安全,因為加密的資料只有用私鑰才能解密。這樣能最大程度確保隨機數的安全。
在內容傳輸階段,使用對稱機密,可以大大提高加解密的效率。
內容傳輸為什麼要使用對稱機密
- 對稱加密效率比較高
- 一對公私鑰只能實現單向的加解密。只有服務端儲存了私鑰。如果使用非對稱機密,相當於客戶端必須有自己的私鑰,這樣設計的話,每個客戶端都有自己的私鑰,這很明顯是不合理的,因為私鑰是需要申請的。
https 是絕對安全的嗎
不是絕對安全的,可以通過中間人攻擊。
什麼是中間人攻擊
中間人攻擊是指攻擊者與通訊的兩端分別建立獨立的聯絡,並交換其所收到的資料,使通訊的兩端認為他們正在通過一個私密的連線與對方直接對話,但事實上整個會話都被攻擊者完全控制。
HTTPS 使用了 SSL 加密協議,是一種非常安全的機制,目前並沒有方法直接對這個協議進行攻擊,一般都是在建立 SSL 連線時,攔截客戶端的請求,利用中間人獲取到 CA證書、非對稱加密的公鑰、對稱加密的金鑰;有了這些條件,就可以對請求和響應進行攔截和篡改。
過程原理:
- 本地請求被劫持(如DNS劫持等),所有請求均傳送到中間人的伺服器
- 中間人伺服器返回中間人自己的證書
- 客戶端建立隨機數,通過中間人證書的公鑰對隨機數加密後傳送給中間人,然後憑隨機數構造對稱加密對傳輸內容進行加密傳輸
- 中間人因為擁有客戶端的隨機數,可以通過對稱加密演算法進行內容解密
- 中間人以客戶端的請求內容再向官方網站發起請求
- 因為中間人與伺服器的通訊過程是合法的,官方網站通過建立的安全通道返回加密後的資料
- 中間人憑藉與官方網站建立的對稱加密演算法對內容進行解密
- 中間人通過與客戶端建立的對稱加密演算法對官方內容返回的資料進行加密傳輸
- 客戶端通過與中間人建立的對稱加密演算法對返回結果資料進行解密
由於缺少對證書的驗證,所以客戶端雖然發起的是 HTTPS 請求,但客戶端完全不知道自己的網路已被攔截,傳輸內容被中間人全部竊取。
https 是如何防止中間人攻擊的
在https中需要證書,證書的作用是為了防止"中間人攻擊"的。 如果有個中間人M攔截客戶端請求,然後M向客戶端提供自己的公鑰,M再向服務端請求公鑰,作為"中介者" 這樣客戶端和服務端都不知道,資訊已經被攔截獲取了。這時候就需要證明服務端的公鑰是正確的.
怎麼證明呢?
就需要權威第三方機構來公正了.這個第三方機構就是CA. 也就是說CA是專門對公鑰進行認證,進行擔保的,也就是專門給公鑰做擔保的擔保公司。 全球知名的CA也就100多個,這些CA都是全球都認可的,比如VeriSign、GlobalSign等,國內知名的CA有WoSign。
上面的內容有誤,正確答案如下
https 無法防止中間人攻擊,只有做證書固定ssl-pinning 或者 apk中預置證書做自簽名驗證可以防中間人攻擊。具體的可以看這一篇文章。
Android中Https請求如何防止中間人攻擊和Charles抓包原理
瀏覽器是如何確保CA證書的合法性?
一、證書包含什麼資訊?
頒發機構資訊、公鑰、公司資訊、域名、有效期、指紋......
二、證書的合法性依據是什麼?
首先,權威機構是要有認證的,不是隨便一個機構都有資格頒發證書,不然也不叫做權威機構。另外,證書的可信性基於信任制,權威機構需要對其頒發的證書進行信用背書,只要是權威機構生成的證書,我們就認為是合法的。所以權威機構會對申請者的資訊進行稽核,不同等級的權威機構對稽核的要求也不一樣,於是證書也分為免費的、便宜的和貴的。
三、瀏覽器如何驗證證書的合法性?
瀏覽器發起HTTPS請求時,伺服器會返回網站的SSL證書,瀏覽器需要對證書做以下驗證:
- 驗證域名、有效期等資訊是否正確。證書上都有包含這些資訊,比較容易完成驗證;
- 判斷證書來源是否合法。每份簽發證書都可以根據驗證鏈查詢到對應的根證書,作業系統、瀏覽器會在本地儲存權威機構的根證書,利用本地根證書可以對對應機構簽發證書完成來源驗證;
- 判斷證書是否被篡改。需要與CA伺服器進行校驗;
- 判斷證書是否已吊銷。通過CRL(Certificate Revocation List 證書登出列表)和 OCSP(Online Certificate Status Protocol 線上證書狀態協議)實現,其中 OCSP 可用於第3步中以減少與CA伺服器的互動,提高驗證效率。
以上任意一步都滿足的情況下瀏覽器才認為證書是合法的。
https 可以抓包嗎
HTTPS 的資料是加密的,常規下抓包工具代理請求後抓到的包內容是加密狀態,無法直接檢視。
但是,我們可以通過抓包工具來抓包。它的原理其實是模擬一箇中間人。
通常 HTTPS 抓包工具的使用方法是會生成一個證書,使用者需要手動把證書安裝到客戶端中,然後終端發起的所有請求通過該證書完成與抓包工具的互動,然後抓包工具再轉發請求到伺服器,最後把伺服器返回的結果在控制檯輸出後再返回給終端,從而完成整個請求的閉環。
關於 httpps 抓包的原理可以看這一篇文章。
有人可能會問了,既然 HTTPS 不能防抓包,那 HTTPS 有什麼意義?
HTTPS 可以防止使用者在不知情的情況下通訊鏈路被監聽,對於主動授信的抓包操作是不提供防護的,因為這個場景使用者是已經對風險知情。要防止被抓包,需要採用應用級的安全防護,例如採用私有的對稱加密,同時做好移動端的防反編譯加固,防止本地演算法被pojie。
擴充套件
如何防止抓包?
對於HTTPS API介面,如何防止抓包呢?既然問題出在證書信任問題上,那麼解決方法就是在我們的APP中預置證書。在TLS/SSL握手時,用預置在本地的證書中的公鑰校驗伺服器的數字簽名,只有簽名通過才能成功握手。由於數字簽名是使用私鑰生成的,而私鑰只掌握在我們手上,中間人無法偽造一個有效的簽名,因此攻擊失敗,無法抓包。
同時,為了防止預置證書被替換,在證書儲存上,可以將證書進行加密後進行「嵌入儲存」,如嵌入在圖片中或一段語音中。這涉及到資訊隱寫的領域,這個話題我們有空了詳細說。
關於 Android 中Https 請求如何防止中間人攻擊和Charles抓包,可以看一下這一篇文章。
Android中Https請求如何防止中間人攻擊和Charles抓包原理
預置證書/公鑰更新問題
這樣做雖然解決了抓包問題,但是也帶來了另外一個問題:我們購買的證書都是有有效期的,到期前需要對證書進行更新。主要有兩種方式:
提供預置證書更新介面。在當前證書快過期時,APP請求獲取新的預置證書,這過渡時期,兩個證書同時有效,直到安全完成證書切換。這種方式有一定的維護成本,且不易測試。
在APP中只預埋公鑰,這樣只要私鑰不變,即使證書更新也不用更新該公鑰。但是,這樣不太符合週期性更新私鑰的安全審計需求。一個折中的方法是,一次性預置多個公鑰,只要任意一個公鑰驗證通過即可。考慮到我們的證書一般購買週期是3-5年,那麼3個公鑰,可以使用9-15年,同時,我們在此期間還可以釋出新版本廢棄老公鑰,新增新公鑰,這樣可以使公鑰一直更新下去。
小結
開頭說到的幾個問題,你能對答如流了嗎
- 什麼是 https,為什麼需要 https
- https 的連線過程
- https 的加密方式是怎樣的,對稱加密和非對稱加密,為什麼要這樣設計?內容傳輸為什麼要使用對稱機密
- https 是絕對安全的嗎
- https 可以抓包嗎
最近在 github 上面更新了一個倉庫,主要是面試資料相關的,有興趣的可以關注一下。Android_interview
推薦閱讀文章