絕大部分iOS程序的后臺服務都是基于RESTful或者WebService的,不論在任何時候,你都應該將服務置于HTTPS上,因為它可以避免中間人攻擊的問題,還自帶了基于非對稱密鑰的加密通道!現實是這些年涌現了大量速成的移動端開發(fā)人員,這些人往往基礎很差,完全不了解加解密為何物,使用HTTPS后,可以省去教育他們各種加解密技術,生活輕松多了。
使用HTTPS有個問題,就是CA證書。缺省情況下,iOS要求連接的HTTPS站點必須為CA簽名過的合法證書,AFNetworking是個iOS上常用的HTTP訪問庫,由于它是基于iOS的HTTP網絡通訊庫,自然證書方面的要求和系統(tǒng)是一致的,也就是你需要有一張合法的站點證書。
正式的CA證書非常昂貴,很多人都知道,AFNetworking2只要通過下面的代碼,你就可以使用自簽證書來訪問HTTPS
2AFSecurityPolicy?*securityPolicy?=?[AFSecurityPolicy?defaultPolicy];
securityPolicy.allowInvalidCertificates?=?YES;
這么做有個問題,就是你無法驗證證書是否是你的服務器后端的證書,給中間人攻擊,即通過重定向路由來分析偽造你的服務器端打開了大門。
解決方法。AFNetworking2是允許內嵌證書的,通過內嵌證書,AFNetworking2就通過比對服務器端證書、內嵌的證書、站點域名是否一致來驗證連接的服務器是否正確。由于CA證書驗證是通過站點域名進行驗證的,如果你的服務器后端有綁定的域名,這是最方便的。將你的服務器端證書,如果是pem格式的,用下面的命令轉成cer格式
openssl?x509?-in<你的服務器證書>.pem?-outform?der?-out?server.cer
然后將生成的server.cer文件,如果有自建ca,再加上ca的cer格式證書,引入到app的bundle里,AFNetworking2在
AFSecurityPolicy?*securityPolicy?=?[AFSecurityPolicy?AFSSLPinningModeCertificate];
或者
AFSecurityPolicy?*securityPolicy?=?[AFSecurityPolicy?AFSSLPinningModePublicKey];
securityPolicy.allowInvalidCertificates?=?YES;//還是必須設成YES
情況下,會自動掃描bundle中.cer的文件,并引入,這樣就可以通過自簽證書來驗證服務器唯一性了。
我前面說過,驗證站點證書,是通過域名的,如果服務器端站點沒有綁定域名(萬惡的備案),僅靠IP地址上面的方法是絕對不行的。怎么辦?答案是想通過設置是不可以的,你只能修改AFNetworking2的源代碼!打開AFSecurityPolicy.m文件,找到方法:
-?(BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString?*)domain
將下面這部分注釋掉
//????????????SecTrustSetAnchorCertificates(serverTrust,?(__bridge?CFArrayRef)pinnedCertificates);
//
//????????????if?(!AFServerTrustIsValid(serverTrust))?{
//????????????????return?NO;
//????????????}
//
//????????????if?(!self.validatesCertificateChain)?{
//????????????????return?YES;
//????????????}
這樣,AFSecurityPolicy就只會比對服務器證書和內嵌證書是否一致,不會再驗證證書是否和站點域名一致了。
這么做為什么是安全的?了解HTTPS的人都知道,整個驗證體系中,最核心的實際上是服務器的私鑰。私鑰永遠,永遠也不會離開服務器,或者以任何形式向外傳輸。私鑰和公鑰是配對的,如果事先在客戶端預留了公鑰,只要服務器端的公鑰和預留的公鑰一致,實際上就已經可以排除中間人攻擊了。
轉載至--http://my.oschina.net/non6/blog/290175