首先介紹一下在https建立的過程中是如何被中間人抓到包的吧,前提是如果不熟悉https建立連接的過程,先看一下相關(guān)資料再接著看本文
移動端防止被抓包
過程分析
- 客戶端首先要向遠(yuǎn)程的服務(wù)器發(fā)送建立連接的請求,并帶有自己的支持的加解密的方式級別,這個過程經(jīng)過了中間人的竊聽,中間人把消息修改后發(fā)給了真正的目的地——服務(wù)端
- 服務(wù)端收到了要建立https鏈接的請求后,會發(fā)送當(dāng)時從證書簽發(fā)機構(gòu)簽發(fā)的公鑰證書。這個過程中中間人又竊聽了,然后中間人替換上自己的證書后又轉(zhuǎn)發(fā)給了客戶端。
- 客戶端收到了中間人發(fā)過來的公鑰證書,驗證證書的真?zhèn)?,并產(chǎn)生隨機的對稱加密的密鑰,用中間人發(fā)的公鑰加密后發(fā)給了中間人。由于剛才客戶端收到的公鑰證書本身就是中間人產(chǎn)生的,所以中間人用相應(yīng)的私鑰就解開了,拿到了客戶端產(chǎn)生的那個隨機產(chǎn)生的對稱加密密鑰。中間人再用剛才服務(wù)端返回的公鑰證書加密這個客戶端產(chǎn)生的用來對稱加密的密鑰,發(fā)給服務(wù)端。
- 服務(wù)端收到了當(dāng)時用自己下發(fā)的公鑰的證書加密的對稱加密密鑰,用自己的私鑰解密,也得到了對稱加密的密鑰。
以后的通信都使用這個對稱加密的密鑰加密了。因為客戶端,中間人,服務(wù)端都有了這個對稱加密的密鑰,所以都可以用此解密通信的內(nèi)容。(上面的步驟是穿插了HTTPS建立握手過程和中間人的作用介紹的,屬于簡潔介紹,明白原理就可以了)。
上面有幾個字“驗證證書的真?zhèn)巍睒?biāo)為了紅色,其實一般來說這個過程應(yīng)該是安全的,因為一般的證書都是由操作系統(tǒng)來管理(Firefox自己管理)的,所以只要操作系統(tǒng)沒有證書鏈驗證等方面的bug是沒有什么問題的,但是為了抓包其實我們是在操作系統(tǒng)中導(dǎo)入了中間人的CA,這樣中間人下發(fā)的公鑰證書就可以被認(rèn)為是合法的,可以通過驗證的(中間人既承擔(dān)了辦法了證書,又承擔(dān)了驗證證書,能不通過驗證嘛)。
解決問題方案
客戶端為了解決這個問題,最好的方式其實就是內(nèi)嵌證書,比對一下這個證書到底是不是自己真正的“服務(wù)端”發(fā)來的,而不是中間被替換了。
下面就介紹一下解決的步驟吧:
1、問運維要到接口站點的證書(即當(dāng)初證書機構(gòu)簽完的那個放到nginx里的公鑰證書),放到工程里面就可以,AF會自動去查找
2、AFNetworking設(shè)置以下代碼
AFSecurityPolicy * policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
_manager.securityPolicy = policy;
AF的安全策略會自動的在bundle里面查找公鑰證書,建立https的時候進(jìn)行比對。不一樣直接就失敗了。
PS:順帶介紹一下AF的AFSSLPinningMode的三個級別
- AFSSLPinningModeNone: (默認(rèn)級別),客戶端無條件信任任何下發(fā)的公鑰證書
- AFSSLPinningModePublicKey: 客戶端本地去驗證服務(wù)端下發(fā)的公鑰證書的 public keys部分。如果正確才通過
- AFSSLPinningModeCertificate: 客戶端本地去驗證服務(wù)端下發(fā)的公鑰證書的所有部分。如果正確才通過
這樣做了之后,就可以即使手機上安裝了抓包工具的CA,抓包工具也不能抓到包了。因為你的客戶端在驗證“服務(wù)端”下發(fā)的公鑰證書的真?zhèn)蔚臅r候就不會通過“中間人”下發(fā)的公鑰證書,也就不會建立起來https的連接了。
其實使用了https,并且在系統(tǒng)沒有被攻破或者有證書漏洞的時候就能保證通信過程的安全了。但是這樣可以更近一步,以防止競爭對手抓取你們的數(shù)據(jù)之類的,畢竟數(shù)據(jù)被別人抓走了總是不好的。在寫這個博文的時候嘗試了一下可以被中間人抓包工具抓到完整包的有很多,知乎,貼吧,等好多。但是銀行的金融類app就抓不到,相對的安全了很多了。