公司的接口一般會兩種協議的,一種HTTP,一種HTTPS的,HTTP 只要請求,服務器就會響應,如果我們不對請求和響應做出加密處理,所有信息都是會被檢測劫持到的,是很不安全的,客戶端加密可以使用本文這套工具類進行處理。
導言
公司的接口一般會兩種協議的,一種HTTP,一種HTTPS的,HTTP 只要請求,服務器就會響應,如果我們不對請求和響應做出加密處理,所有信息都是會被檢測劫持到的,是很不安全的,客戶端加密可以使用本文這套工具類進行處理。
但是不論在任何時候,都應該將服務置於HTTPS上,因為它可以避免中間人攻擊的問題,還自帶了基於非對稱密鑰的加密通道。
HTTPS交互原理
簡答說,HTTPS 就是 HTTP協議加了一層SSL協議的加密處理,SSL 證書就是遵守 SSL協議,由受信任的數字證書頒發機構CA(如GlobalSign,wosign),在驗證服務器身份後頒發,這是需要花錢滴,簽發後的證書作為公鑰一般放在服務器的根目錄下,便於客戶端請求返回給客戶端,私鑰在服務器的內部中心保存,用於解密公鑰。
HTTPS 客戶端與服務器交互過程:
1)客戶端發送請求,服務器返回公鑰給客戶端;
2)客戶端生成對稱加密秘鑰,用公鑰對其進行加密後,返回給服務器;
3)服務器收到後,利用私鑰解開得到對稱加密秘鑰,保存;
4)之後的交互都使用對稱加密後的數據進行交互。
證書
簡單說,證書有兩種,一種是正經的:
CA頒發的證書
一種是不正經的:
自己生成簽發的證書
我們需要做什麼
如果遇到正經的證書,我們直接用AFNetworking 直接請求就好了,AFNetworking 內部幫我們封裝了HTTPS的請求方式,但是大部分公司接口都是不正經的證書,這時需要我們做以下幾步:
1)將服務器的公鑰證書拖到Xcode中
2)修改驗證模式
manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];
原理
簡單來說,就是你本可以修改AFN這個設置來允許客戶端接收服務器的任何證書,但是這麼做有個問題,就是你無法驗證證書是否是你的服務器後端的證書,給中間人攻擊,即通過重定向路由來分析偽造你的服務器端打開了大門。
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
securityPolicy.allowInvalidCertificates = YES;
解決方法
AFNetworking是允許內嵌證書的,通過內嵌證書,AFNetworking就通過比對服務器端證書、內嵌的證書、站點域名是否一致來驗證連接的服務器是否正確。由於CA證書驗證是通過站點域名進行驗證的,如果你的服務器後端有綁定的域名,這是最方便的。將你的服務器端證書,如果是pem格式的,用下面的命令轉成cer格式
openssl x509 -in <你的服務器證書>.pem -outform der -out server.cer
然後將生成的server.cer文件,如果有自建ca,再加上ca的cer格式證書,引入到app的bundle裡,AFNetworking在
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModeCertificate];
或者
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModePublicKey];
情況下,會自動掃描bundle中。cer的文件,並引入,這樣就可以通過自簽證書來驗證服務器唯一性了。
AFSecurityPolicy三種驗證模式
AFSSLPinningModeNone
這個模式表示不做SSL pinning,
只跟浏覽器一樣在系統的信任機構列表裡驗證服務端返回的證書。若證書是信任機構簽發的就會通過,若是自己服務器生成的證書就不會通過。
AFSSLPinningModeCertificate這個模式表示用證書綁定方式驗證證書,需要客戶端保存有服務端的證書拷貝,這裡驗證分兩步,第一步驗證證書的域名有效期等信息,第二步是對比服務端返回的證書跟客戶端返回的是否一致。
AFSSLPinningModePublicKey
這個模式同樣是用證書綁定方式驗證,客戶端要有服務端的證書拷貝,
只是驗證時只驗證證書裡的公鑰,不驗證證書的有效期等信息。只要公鑰是正確的,就能保證通信不會被竊聽,因為中間人沒有私鑰,無法解開通過公鑰加密的數據。