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