轉至:http://www.cnblogs.com/jys509/p/5001566.htmlhtml
通常來說若是app用了web service , 咱們須要防止數據嗅探來保證數據安全.一般的作法是用ssl來鏈接以防止數據抓包和嗅探web
其實這麼作的話仍是不夠的 。 咱們還須要防止中間人攻擊(不明白的本身去百度)。攻擊者經過僞造的ssl證書使app鏈接到了假裝的假冒的服務器上,這是個嚴重的問題!那麼如何防止中間人攻擊呢?xcode
首先web服務器必須提供一個ssl證書,須要一個 .crt 文件,而後設置app只能鏈接有效ssl證書的服務器。安全
在開始寫代碼前,先要把 .crt 文件轉成 .cer 文件,而後在加到xcode 裏面服務器
1.使用openssl 進行轉換session
openssl x509 -in 你的證書.crt -out 你的證書.cer -outform der
2.經過安裝crt文件,電腦導出app
1)先打開「鑰匙串訪問」google
2)選中你安裝的crt文件證書,選擇「文件」--》「導出項目」加密
3)選擇.cer證書,存儲便可。url
實際上,很簡單,只須要兩步。
@interface AppDelegate :.h
+(AFSecurityPolicy*)customSecurityPolicy;//ssljiami
第一步:新增一個類
@interface AppDelegate :.m
+ (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; }
第二步:直接在請求方法里加入,只有一行代碼
#import "FenLei_two_Request.h" @implementation FenLei_two_Request + (void)loadData:(FenLei_two_Parm *)param Withsuccess:(void (^)(FenLei_two_Result *result))success failure:(void (^)(NSError *error))failure{ AFHTTPSessionManager *session = [AFHTTPSessionManager manager]; session.requestSerializer = [AFJSONRequestSerializer serializer]; session.responseSerializer = [AFHTTPResponseSerializer serializer]; session.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"]; NSMutableDictionary *dic = [NSMutableDictionary dictionary]; if (param.category_id) { dic[@"category_id"] = param.category_id; } if (param.sort) { dic[@"sort"] = param.sort; } if (param.trade_type) { dic[@"trade_type"] = param.trade_type; } if (param.page) { dic[@"page"] = param.page; } NSString *url = [NSString stringWithFormat:@"%@/tob_home",onlineHttp]; #ifdef IOS_DEBUG #else //SSL加密 [session setSecurityPolicy:[AppDelegate customSecurityPolicy]]; #endif [session POST:url parameters:dic progress:^(NSProgress * _Nonnull uploadProgress) { } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { FenLei_two_Result *result = [FenLei_two_Result mj_objectWithKeyValues:responseObject]; // NSLog(@"%@",responseObject); if (success && responseObject) { success(result); } } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { if (error) { failure(error); } NSLog(@"error---%@",error); }]; } @end
接下來,咱們經過Charles抓取數據,抓到的數據已經加密。
1)證書必定要拉到項目裏面,AFN加了驗證以後,看看獲取證書的certData是否爲空。若是爲空,則證書有問題
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
2)若是https服務器沒有數據返回,很大多是由於服務器配置出了問題。
3)錯誤說「Error Domain=kCFErrorDomainCFNetwork Code=-1004」 ,是沒有配支持http的請求,解決以下
附Demo: http://download.csdn.net/detail/jys1216/9412638
注:因爲cer證書是真實的項目在用,不便提供,因些Demo裏的cer證書和請求連接都是有誤的。請替換使用。
demo裏的cer文件,我是在AFN裏找的,certData是有數據的。