引用自 http://www.cnblogs.com/jys509/p/5001566.htmlcss
通常來說若是app用了web service , 咱們須要防止數據嗅探來保證數據安全.一般的作法是用ssl來鏈接以防止數據抓包和嗅探html
其實這麼作的話仍是不夠的 。 咱們還須要防止中間人攻擊(不明白的本身去百度)。攻擊者經過僞造的ssl證書使app鏈接到了假裝的假冒的服務器上,這是個嚴重的問題!那麼如何防止中間人攻擊呢?git
首先web服務器必須提供一個ssl證書,須要一個 .crt 文件,而後設置app只能鏈接有效ssl證書的服務器。web
在開始寫代碼前,先要把 .crt 文件轉成 .cer 文件,而後在加到xcode 裏面shell
可使用openssl 進行轉換後端
openssl x509 -in 你的證書.crt -out 你的證書.cer -outform der
使用AFNetworking 對數據進行只須要兩步xcode
第一步:新增一個類安全
+ (AFSecurityPolicy*)customSecurityPolicy { // /先導入證書 NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"hgcang" ofType:@"cer"];//證書的路徑 NSData *certData = [NSData dataWithContentsOfFile:cerPath]; // AFSSLPinningModeCertificate 使用證書驗證模式 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; // allowInvalidCertificates 是否容許無效證書(也就是自建的證書),默認爲NO // 若是是須要驗證自建證書,須要設置爲YES securityPolicy.allowInvalidCertificates = YES; //validatesDomainName 是否須要驗證域名,默認爲YES; //假如證書的域名與你請求的域名不一致,需把該項設置爲NO;如設成NO的話,即服務器使用其餘可信任機構頒發的證書,也能夠創建鏈接,這個很是危險,建議打開。 //置爲NO,主要用於這種狀況:客戶端請求的是子域名,而證書上的是另一個域名。由於SSL證書上的域名是獨立的,假如證書上註冊的域名是www.google.com,那麼mail.google.com是沒法驗證經過的;固然,有錢能夠註冊通配符的域名*.google.com,但這個仍是比較貴的。 //如置爲NO,建議本身添加對應域名的校驗邏輯。 securityPolicy.validatesDomainName = NO; securityPolicy.pinnedCertificates = @[certData]; return securityPolicy; }
第二步:直接在請求方法里加入,只有一行代碼服務器
+ (void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure { // 1.得到請求管理者 AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager]; // 2.申明返回的結果是text/html類型 mgr.responseSerializer = [AFHTTPResponseSerializer serializer]; // 加上這行代碼,https ssl 驗證。 //[mgr setSecurityPolicy:[self customSecurityPolicy]]; // 3.發送POST請求 [mgr POST:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObj) { if (success) { success(responseObj); } } failure:^(AFHTTPRequestOperation *operation, NSError *error) { if (failure) { failure(error); } }]; }
2 引用:http://my.oschina.net/non6/blog/290175 網絡
友情提示:本文使用的AFNetworking是最新git pull的2.3.1版本,若是想確認你機器上的AFNetworking版本,請打git tag命令查看。
絕大部分iOS程序的後臺服務都是基於RESTful或者WebService的,不論在任什麼時候候,你都應該將服務置於HTTPS上,由於它能夠避免中間人攻擊的問題,還自帶了基於非對稱密鑰的加密通道!現實是這些年涌現了大量速成的移動端開發人員,這些人每每基礎不好,徹底不瞭解加解密爲什麼物,使用HTTPS後,能夠省去教育他們各類加解密技術,生活輕鬆多了。
使用HTTPS有個問題,就是CA證書。缺省狀況下,iOS要求鏈接的HTTPS站點必須爲CA簽名過的合法證書,AFNetworking是個iOS上經常使用的HTTP訪問庫,因爲它是基於iOS的HTTP網絡通信庫,天然證書方面的要求和系統是一致的,也就是你須要有一張合法的站點證書。
正式的CA證書很是昂貴,不少人都知道,AFNetworking2只要經過下面的代碼,你就可使用自簽證書來訪問HTTPS
1
2
|
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
securityPolicy.allowInvalidCertificates = YES;
|
這麼作有個問題,就是你沒法驗證證書是不是你的服務器後端的證書,給中間人攻擊,即經過重定向路由來分析僞造你的服務器端打開了大門。
解決方法。AFNetworking2是容許內嵌證書的,經過內嵌證書,AFNetworking2就經過比對服務器端證書、內嵌的證書、站點域名是否一致來驗證鏈接的服務器是否正確。因爲CA證書驗證是經過站點域名進行驗證的,若是你的服務器後端有綁定的域名,這是最方便的。將你的服務器端證書,若是是pem格式的,用下面的命令轉成cer格式
1
|
openssl x509 -
in
<你的服務器證書>.pem -outform der -out server.cer
|
而後將生成的server.cer文件,若是有自建ca,再加上ca的cer格式證書,引入到app的bundle裏,AFNetworking2在
1
2
3
4
|
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModeCertificate];
或者
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy AFSSLPinningModePublicKey];
securityPolicy.allowInvalidCertificates = YES;
//仍是必須設成YES
|
狀況下,會自動掃描bundle中.cer的文件,並引入,這樣就能夠經過自簽證書來驗證服務器惟一性了。
我前面說過,驗證站點證書,是經過域名的,若是服務器端站點沒有綁定域名(萬惡的備案),僅靠IP地址上面的方法是絕對不行的。怎麼辦?答案是想經過設置是不能夠的,你只能修改AFNetworking2的源代碼!打開AFSecurityPolicy.m文件,找到方法:
1
2
|
- (
BOOL
)evaluateServerTrust:(SecTrustRef)serverTrust
forDomain:(NSString *)domain
|
將下面這部分註釋掉
1
2
3
4
5
6
7
8
9
|
// SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
//
// if (!AFServerTrustIsValid(serverTrust)) {
// return NO;
// }
//
// if (!self.validatesCertificateChain) {
// return YES;
// }
|
這樣,AFSecurityPolicy就只會比對服務器證書和內嵌證書是否一致,不會再驗證證書是否和站點域名一致了。
這麼作爲何是安全的?瞭解HTTPS的人都知道,整個驗證體系中,最核心的其實是服務器的私鑰。私鑰永遠,永遠也不會離開服務器,或者以任何形式向外傳輸。私鑰和公鑰是配對的,若是事先在客戶端預留了公鑰,只要服務器端的公鑰和預留的公鑰一致,實際上就已經能夠排除中間人攻擊了。
iOS安全系列之一:HTTPS :http://oncenote.com/2014/10/21/Security-1-HTTPS/