Android程序员面试必须要掌握的:Https加密原理、中间人攻击到底是怎么回事
前言–閱讀本文你將收獲
1.https加密的基本原理與過程,https為什么是安全的?
2.什么是中間人攻擊,中間人攻擊的基本原理
3.如何防止中間人攻擊
作者:RicardoMJiang
鏈接:https://juejin.im/post/6880024440143347719
https加密的基本原理
https要完成的目的
1.Client必須要能確定,它要訪問的Server確實是正確的Server
2.Client和Server交流的信息不能被其它第三方竊聽
3.當然,針對第1點,反過來,Server也可以要求,必須確認Client是它想通信的正確的Client,不過道理和1一樣,這里不展開
通過HTTPS握手建立加密信道來保證上述要求
https三次握手
三次握手過程如下:
看了上述三次握手過程,可以知道,handshake主要完成的事情:
1.客戶端&服務端通信,協(xié)商加密方式
2.客戶端(Client)和服務端(Server)互相確認身份
3.雙方安全地交換https通信使用的密鑰(Session Key)
第一階段:C&S協(xié)商加密方式
客戶端向服務端發(fā)送ClientHello信息,信息主要包括客戶端支持的加密方式、客戶端支持的SSL版本等;服務端接收到ClientHello信息后,向客戶端發(fā)送一個ServerHello信息,主要是告訴客戶端它將使用什么加密方式和SSL版本。
第二階段:身份校驗
階段2主要是,客戶端&服務端互相校驗對方身份
客戶端與服務端之間驗證身份是通過證書完成的
1.關于證書:
服務端向客戶端下發(fā)自己的證書,通常是CA認證的證書。證書包括了很多信息,主要有“公鑰信息”、“簽名”、“組織機構地區(qū)等信息”、“證書頒發(fā)機構”,關聯的中級證書(medium certificate)、根證書(root certificate)等。
X.509 應該是比較流行的 SSL 數字證書標準,包含(但不限于)以下的字段:
| 對象名稱(Subject Name) | 用于識別該數字證書的信息 |
| 共有名稱(Common Name) | 對于客戶證書,通常是相應的域名 |
| 證書頒發(fā)者(Issuer Name) | 發(fā)布并簽署該證書的實體的信息 |
| 簽名算法(Signature Algorithm) | 簽名所使用的算法 |
| 序列號(Serial Number) | 數字證書機構(Certificate Authority, CA)給證書的唯一整數,一個數字證書一個序列號 |
| 生效期(Not Valid Before) | (`?ω?′) |
| 失效期(Not Valid After) | (╯°口°)╯(┴—┴ |
| 公鑰(Public Key) | 可公開的密鑰 |
| 簽名(Signature) | 通過簽名算法計算證書內容后得到的數據,用于驗證證書是否被篡改 |
主要就是簽名,用于驗證是否篡改過
2.客戶端如何通過證書確定服務端的身份?
證明下面兩點,(然后才可以使用證書上的公鑰來加密生成Session key的隨機數)
證書以證書鏈的形式組織,在頒發(fā)證書的時候首先要有根CA機構頒發(fā)的根證書,再由根CA機構頒發(fā)一個中級CA機構的證書,最后由中級CA機構頒發(fā)具體的SSL證書。
數字證書采用信任鏈驗證。數字證書的信任錨(信任的起點)就是根證書頒發(fā)機構。根證書(root certificate)是一個無簽名或自簽名的證書。是用于識別根證書頒發(fā)機構(CA)的公鑰證書。
驗證的具體實現如下圖所示:
如何驗證證書
1.如何驗證證書沒有被篡改過
比如驗證用戶證書A,需要用到中級證書的公鑰B解密前者的簽名得到摘要 Digest1,我們的客戶端也計算A證書的內容得到摘要 Digest2。對比這兩個摘要就能知道前者是否被篡改。后者同理,使用他的證書簽發(fā)者提供的公鑰驗證。當驗證到到受信任的根證書時,就能確定這個證書是可信的。
2.為什么根證書是可信的
數字證書認證機構(Certificate Authority, CA)簽署和管理的 CA 根證書,會被納入到你的瀏覽器和操作系統(tǒng)的可信證書列表中,并由這個列表判斷根證書是否可信。所以不要隨便導入奇奇怪怪的根證書到你的操作系統(tǒng)中。
第三階段:產生通信密鑰
前面講過,第1階段,服務端告知了客戶端后面要使用的加密方式(普遍都是對稱加密,因為非對稱加密成本太高,速度低下)。
第2階段,客戶端驗證服務端證書是正確的,即,證書上標明的公鑰拿來加密信息,加密后的信息,只有該服務端能解密,其它第三方無法解密。 那么在第三階段,客戶端產生了第三個隨機數,這個隨機數稱為PMSc(a premaster secret,46 bytes ),使用服務端的公鑰對PMSc加密,然后上送給服務端。服務端取到這個密文后,用自己的私鑰解密,得到PMSc。
好了,接下來最重要的一步來了:根據之前協(xié)商好的加密方式,以及3個隨機數,客戶端、服務端各自產生出通信密鑰,該密鑰稱為Master Secret,簡稱MS,也稱Session Key。這個密鑰雖然是各自產生的,但是產生后是一致的。
第四階段:加密信道已經建立
客戶端,服務端各自產生了通信密鑰后,就用這個相同的MS對往后的所有通信信息進行加密。而這個密鑰,第三方是不知道的,第三方盡管去窺探,但是他們看不懂信息,所以效果相當于,客戶端&服務端在一個加密信道中通信。
從上面可以看出,https通信過程是對稱與非對稱加密混合的
中間人攻擊與https抓包
一個針對SSL的中間人攻擊過程如下:
中間人其實是做了一個偷梁換柱的動作,核心是如何欺騙客戶端,從而讓客戶端能夠放心的與中間人進行數據交互而沒有任何察覺。我們來看Charles如何做到HTTPS抓包的,網上有很多fiddlers如何抓HTTPS包的教程,幾步就搞定了,其中最核心的就是:
將私有CA簽發(fā)的數字證書安裝到手機中并且作為受信任證書保存
當私有的CA證書添加到系統(tǒng)信任證書后,就可以完成證書鏈驗證過程
fiddler抓包過程,詳情可見:www.cnblogs.com/afeng2010/p…
android7.0之后用戶CA限制
Android從7.0開始系統(tǒng)不再信任用戶CA證書(應用targetSdkVersion >= 24時生效,如果targetSdkVersion < 24即使系統(tǒng)是7.0+依然會信任)。也就是說即使安裝了用戶CA證書,在Android 7.0+的機器上,targetSdkVersion >= 24的應用的HTTPS包就抓不到了。
Android 6.0(API 23)及更低版本應用的默認網絡安全性配置如下:
<!-- 默認允許所有明文通信 --> <base-config cleartextTrafficPermitted="true"><trust-anchors><!-- 信任系統(tǒng)預裝 CA 證書 --><certificates src="system" /><!-- 信任用戶添加的 CA 證書,Charles 和 Fiddler 抓包工具安裝的證書屬于此類 --><certificates src="user" /></trust-anchors> </base-config>而在 Android 7.0(API 24)到 Android 8.1(API 27)的默認網絡安全性配置如下:
<!-- 默認允許所有明文通信 --> <base-config cleartextTrafficPermitted="true"><trust-anchors><!-- 信任系統(tǒng)預裝 CA 證書 --><certificates src="system" /></trust-anchors> </base-config>而在 Android 9.0(API 28)及更高版本的默認網絡安全性配置如下:
<!-- 默認禁止所有明文通信 --> <base-config cleartextTrafficPermitted="false"><trust-anchors><!-- 信任系統(tǒng)預裝 CA 證書 --><certificates src="system" /></trust-anchors> </base-config>如果我們要抓自已APP的包,解決方式就是使用 Android 6.0 以下的網絡安全性配置: 添加res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config><base-config cleartextTrafficPermitted="true"><trust-anchors><certificates src="system" /><certificates src="user" /></trust-anchors></base-config> </network-security-config>然后在清單文件中指向該文件:
<?xml version="1.0" encoding="utf-8"?> <manifest ... ><application android:networkSecurityConfig="@xml/network_security_config"... >...</application> </manifest>如何防止中間人攻擊
通過上面的講解,大家可以知道
假設你的設備沒有安裝信任過來歷不明的證書,那么不管在任何WIFI或者網絡環(huán)境下,通常HTTPS通信都是安全的
并且在android7.0及以上,就算手機安裝信任了證書,在一般情況下也是安全的,因為android7.0以上默認不信任用戶證書
所以通常情況下,我們不需要做什么特別操作來防止中間人攻擊
不過有部分金融類的APP需要額外校驗來保證https的安全性
我們可以下載服務器端公鑰證書,然后將公鑰證書編譯到Android應用中一般在assets文件夾保存,由應用在交互過程中去驗證證書的合法性。
//使用內置證書public static SSLSocketFactory getSSLSocketFactory_Certificate(Context context) {try {//獲取X.509格式的內置證書CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());keyStore.load(null);Collection<? extends Certificate> cers = certificateFactory.generateCertificates(context.getAssets().open("CACertificate.cer"));int index = 0;for (Certificate certificate : cers) {String certificateAlias = Integer.toString(index++);keyStore.setCertificateEntry(certificateAlias, certificate);}//用這個KeyStore去引導生成的TrustManager來提供驗證final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());trustManagerFactory.init(keyStore);//用TrustManager生成SSLContextSSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());//SSLContext返回SSLSocketFactoryreturn sslContext.getSocketFactory();} catch (Exception e) {throw new RuntimeException(e);}}總結
本文主要介紹了https的基本流程與原理,并介紹了中間人攻擊的原理與預防,希望對大家有所幫助。
關于HTTPS更多面試點,也可以看看這篇文章字節(jié)一面:https 真的安全嗎?可以抓包嗎?如何防止抓包?
文末
一個月前答應大伙的備戰(zhàn)金九銀十,大廠面試真題來啦!
這份資料我從春招開始,就會將各博客、論壇。網站上等優(yōu)質的Android開發(fā)中高級面試題收集起來,然后全網尋找最優(yōu)的解答方案。每一道面試題都是百分百的大廠面經真題+最優(yōu)解答。包知識脈絡 + 諸多細節(jié)。
節(jié)省大家在網上搜索資料的時間來學習,也可以分享給身邊好友一起學習。
給文章留個小贊,就可以免費領取啦~
戳我領取:Android對線暴打面試指南、超硬核Android面試知識筆記、3000頁Android開發(fā)者架構師核心知識筆記
《960全網最全Android開發(fā)筆記》
《379頁Android開發(fā)面試寶典》
包含了騰訊、百度、小米、阿里、樂視、美團、58、獵豹、360、新浪、搜狐等一線互聯網公司面試被問到的題目。熟悉本文中列出的知識點會大大增加通過前兩輪技術面試的幾率。
如何使用它?
1.可以通過目錄索引直接翻看需要的知識點,查漏補缺。
2.五角星數表示面試問到的頻率,代表重要推薦指數
《507頁Android開發(fā)相關源碼解析》
只要是程序員,不管是Java還是Android,如果不去閱讀源碼,只看API文檔,那就只是停留于皮毛,這對我們知識體系的建立和完備以及實戰(zhàn)技術的提升都是不利的。
真正最能鍛煉能力的便是直接去閱讀源碼,不僅限于閱讀各大系統(tǒng)源碼,還包括各種優(yōu)秀的開源庫。
騰訊、字節(jié)跳動、阿里、百度等BAT大廠 2019-2020面試真題解析
資料已經上傳在我的GitHub,或者關注后私信我【666】即可領取(無償)。
資料收集不易,如果大家喜歡這篇文章,或者對你有幫助不妨多多點贊轉發(fā)關注哦。文章會持續(xù)更新的。絕對干貨!!!
總結
以上是生活随笔為你收集整理的Android程序员面试必须要掌握的:Https加密原理、中间人攻击到底是怎么回事的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MDZZ我只想吐槽而已
- 下一篇: 秋招进展