iOS之Https自簽名證書認(rèn)證及數(shù)據(jù)請求的封裝原理
摘要: 在WWDC 2016開發(fā)者大會上,蘋果宣布了一個最后期限:到2017年1月1日 App Store中的所有應(yīng)用都必須啟用 App Transport Security安全功能。App Transport Security(ATS)是蘋果在iOS 9中引入的一項隱私保護(hù)功能,屏蔽明文HTTP資源加載,連接必須經(jīng)過更安全的HTTPS。蘋果目前允許開發(fā)者暫時關(guān)閉ATS,可以繼續(xù)使用HTTP連接,但到年底所有官方商店的應(yīng)用都必須強(qiáng)制性使用ATS。
項目中使用的框架是AFNetworking 3.0及以上版本,由于ATS的原因,iOS只允許使用Https開頭的鏈接,在2016年12月30日以前蘋果允許繞開ATS,如下圖所示:

但是從2017年1月1日開始將不再接受使用http加載資源的應(yīng)用,因此本篇文章主要講解如何使用AFN進(jìn)行自簽名證書的通過認(rèn)證(注:對于使用CA機(jī)構(gòu)認(rèn)證的證書不需要進(jìn)行認(rèn)證,直接使用Https開頭的鏈接進(jìn)行數(shù)據(jù)訪問和加載頁面即可)項目已經(jīng)上傳至GitHub(需要參考源碼的話請點(diǎn)擊鏈接):HttpsSignatureCertificate_jb51.rar
1,建立一個根類 此處命名為AKNetPackegeAFN
1> .h文件 ,創(chuàng)建所需要的Get 與 Post 方法
#import <Foundation/Foundation.h>
typedef enum{
AKNetWorkGET , /**< GET請求 */
AKNetWorkPOST = 1 /**< POST請求 */
}AKNetWorkType;
typedef void (^HttpSuccess)(id json);
typedef void (^HttpErro)(NSError* error);
@interface AKNetPackegeAFN : NSObject
+(instancetype)shareHttpManager;
/*
*
netWorkType:請求方式 GET 或 POST
signature:是否使用簽名證書,是的話直接寫入證書名字,否的話填nil
api:請求的URL接口
parameters:請求參數(shù)
sucess:請求成功時的返回值
fail:請求失敗時的返回值
*
*/
- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail;
@end
2> .m文件,導(dǎo)入頭文件AFNetworking.h 新建Manager 屬性并實現(xiàn)shareHttpManager類方法
#import "AKNetPackegeAFN.h"
#import "AFNetworking.h"
@interface AKNetPackegeAFN()
@property (nonatomic,strong) AFHTTPSessionManager *manager;
@end
@implementation AKNetPackegeAFN
+(instancetype)shareHttpManager{
static dispatch_once_t onece = 0;
static AKNetPackegeAFN *httpManager = nil;
dispatch_once(&onece, ^(void){
httpManager = [[self alloc]init];
});
return httpManager;
}
2,Get 與Post 方法的實現(xiàn)
使用時將后臺所給的證書轉(zhuǎn)換為 .cer格式 拖入項目根目錄中,在方法中進(jìn)行綁定即可例如后臺給的證書名為:Kuture.crt 收到證書后雙擊進(jìn)行安裝,然后打開鑰匙串,將名為Kuture的證書右擊導(dǎo)出,選擇后綴為.cer 然后確定即可 如下圖所示:
-->
-->
--> 
GET 與 POST 實現(xiàn)方法的封裝
- (void)netWorkType:(AKNetWorkType)netWorkType Signature:(NSString *)signature API:(NSString *)api Parameters:(NSDictionary *)parameters Success:(HttpSuccess)sucess Fail:(HttpErro)fail{
//開啟證書驗證模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
//是否允許使用自簽名證書
signature == nil ? (void)(securityPolicy.allowInvalidCertificates = NO):(securityPolicy.allowInvalidCertificates = YES);
//是否需要驗證域名
securityPolicy.validatesDomainName = NO;
_manager = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:api]];
_manager.responseSerializer = [AFJSONResponseSerializer serializer];
_manager.securityPolicy = securityPolicy;
_manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"application/xml",@"text/xml",@"text/json",@"text/plain",@"text/javascript",@"text/html", nil];
if (signature != nil){
__weak typeof(self) weakSelf = self;
[_manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *_credential) {
//獲取服務(wù)器的 trust object
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
//導(dǎo)入自簽名證書
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"你的證書名字" ofType:@"cer"];
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
if (!cerData) {
NSLog(@"==== .cer file is nil ====");
return 0;
}
NSArray *cerArray = @[cerData];
weakSelf.manager.securityPolicy.pinnedCertificates = cerArray;
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cerData);
NSCAssert(caRef != nil, @"caRef is nil");
NSArray *caArray = @[(__bridge id)(caRef)];
NSCAssert(caArray != nil, @"caArray is nil");
//將讀取到的證書設(shè)置為serverTrust的根證書
OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
SecTrustSetAnchorCertificatesOnly(serverTrust, NO);
NSCAssert(errSecSuccess == status, @"SectrustSetAnchorCertificates failed");
//選擇質(zhì)詢認(rèn)證的處理方式
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
__autoreleasing NSURLCredential *credential = nil;
//NSURLAuthenTicationMethodServerTrust質(zhì)詢認(rèn)證方式
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
//基于客戶端的安全策略來決定是否信任該服務(wù)器,不信任則不響應(yīng)質(zhì)詢
if ([weakSelf.manager.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
//創(chuàng)建質(zhì)詢證書
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
//確認(rèn)質(zhì)詢方式
if (credential) {
disposition = NSURLSessionAuthChallengeUseCredential;
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
//取消挑戰(zhàn)
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
}
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
return disposition;
}];
}
if (netWorkType == 0){
[_manager GET:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (sucess){
sucess(responseObject);
}else{
NSLog(@"鏈接異?;蚓W(wǎng)絡(luò)不存在");
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
fail(error);
}];
}else if (netWorkType == 1){
[_manager POST:api parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (sucess){
sucess(responseObject);
}else{
NSLog(@"鏈接異?;蚓W(wǎng)絡(luò)不存在");
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
fail(error);
}];
}
}
2 使用方法,在需要進(jìn)行數(shù)據(jù)獲取或傳遞的類里面,直接導(dǎo)入頭文件 AKNetPackegeAFN.h ,并實現(xiàn)方法即可,如下所示:
//創(chuàng)建對象
//如果是自簽名證書,使用前先到AKNetPackegeAFN相應(yīng)的方法里進(jìn)行證書的綁定(證書直接拖入項目中)即可
/*
*
netWorkType:請求方式 GET 或 POST
signature:是否使用簽名證書,是的話直接寫入證書名字,否的話填nil
api:請求的URL接口
parameters:請求參數(shù)
sucess:請求成功時的返回值
fail:請求失敗時的返回值
*
*/
AKNetPackegeAFN *netHttps = [AKNetPackegeAFN shareHttpManager];
[netHttps netWorkType:請求類型 Signature:證書名稱 API:請求URL Parameters:參數(shù) Success:^(id json) {
NSLog(@"Json:%@",json);
} Fail:^(NSError *error) {
NSLog(@"Error:%@",error);
}];
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- iOS實現(xiàn)電子簽名
- iOS mobileconfig配置文件進(jìn)行簽名的配置方法
- iOS 超級簽名之描述文件的實現(xiàn)過程
- iOS應(yīng)用腳本重簽名的實現(xiàn)方法
- iOS APP簽名機(jī)制原理詳解
- 詳解IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗解決方案
- Android和iOS包批量重簽名
- iOS安全防護(hù)系列之重簽名防護(hù)與sysctl反調(diào)試詳解
- iOS 基于AFNetworking下自簽名證書配置的方法
- iOS中的ipa重簽名(逆向必備)
- IOS 簽名錯誤codesign failed with exit code 1解決方法
- ios的簽名機(jī)制詳解
相關(guān)文章
全面解析iOS應(yīng)用中自定義UITableViewCell的方法
這篇文章主要介紹了iOS應(yīng)用開發(fā)中自定義UITableViewCell的方法,示例為傳統(tǒng)的Obejective-C語言,需要的朋友可以參考下2016-04-04
詳解適配iOS10 的相關(guān)權(quán)限設(shè)置
在最新版本的iOS10系統(tǒng)中,如果你的項目中訪問了隱私數(shù)據(jù),比如:相機(jī)、相冊、錄音、定位、聯(lián)系人等等。涉及到權(quán)限問題,本篇文章主要介紹了適配iOS10 的相關(guān)權(quán)限設(shè)置,有興趣的可以了解一下。2016-12-12
IOS如何使用CAShapeLayer實現(xiàn)復(fù)雜的View的遮罩效果
這篇文章主要為大家詳細(xì)介紹了IOS如何使用CAShapeLayer實現(xiàn)復(fù)雜的View的遮罩效果,感興趣的小伙伴們可以參考一下2016-03-03
iOS中模態(tài)Model視圖跳轉(zhuǎn)和Push視圖跳轉(zhuǎn)的需求實現(xiàn)方法
這篇文章主要介紹了iOS中模態(tài)Model視圖跳轉(zhuǎn)和Push視圖跳轉(zhuǎn)的需求實現(xiàn),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-12-12
iOS指紋驗證TouchID應(yīng)用學(xué)習(xí)教程2
這篇文章主要為大家詳細(xì)iOS指紋驗證TouchID應(yīng)用學(xué)習(xí)教程的第一篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01

