iOS 利用NSURLSession 對HTTPS進行雙向認證

前段是時間做項目要求進行雙向認證屡萤,網(wǎng)上的查了很多都是不全的灯抛,今天將我整理之后的分享給大家沃疮。

廢話不多說直接上最主要的代碼(這里主要是在NSURLSession的 didReceiveChallenge: 代理方法里進行操作)职辅。



// 當對https請求時都會走此代理

```

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge

completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler

{

NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;

NSURLCredential *credential = nil;

// 服務器驗證

if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])

{

/* 調用自定義的驗證過程 */

if ([self myCustomValidation:challenge]) {

credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

if (credential) {

disposition = NSURLSessionAuthChallengeUseCredential;

}

} else {

/* 無效的話蹬挺,取消 */

disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;

}

}else if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])

{//客戶端認證

NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];

NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];

CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);

SecIdentityRef identity;

// 讀取p12證書中的內容

OSStatus result = [self extractP12Data:inPKCS12Data toIdentity:&identity];

if(result != errSecSuccess){

completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);

return;

}

SecCertificateRef certificate = NULL;

SecIdentityCopyCertificate (identity, &certificate);

const void *certs[] = {certificate};

CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);

credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)CFBridgingRelease(certArray) persistence:NSURLCredentialPersistencePermanent];

if (credential) {

disposition = NSURLSessionAuthChallengeUseCredential;

}

}

if (completionHandler) {

completionHandler(disposition, credential);

}

}

```

-(OSStatus) extractP12Data:(CFDataRef)inP12Data toIdentity:(SecIdentityRef*)identity {

OSStatus securityError = errSecSuccess;

CFStringRef password = CFSTR("the_password");//證書密碼

const void *keys[] = { kSecImportExportPassphrase };

const void *values[] = { password };

CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);

securityError = SecPKCS12Import(inP12Data, options, &items);

if (securityError == 0) {

CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);

const void *tempIdentity = NULL;

tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);

*identity = (SecIdentityRef)tempIdentity;

}

if (options) {

CFRelease(options);

}

return securityError;

}

```

- (BOOL)myCustomValidation:(NSURLAuthenticationChallenge *)challenge

{

//獲取trust object

SecTrustRef trust = challenge.protectionSpace.serverTrust;

SecTrustResultType result;

//導入證書

NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"cer"];; //證書的路徑

NSData * cerData = [NSData dataWithContentsOfFile:cerPath];

SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(cerData));

NSMutableArray *trustedCertificates = [NSMutableArray new];

[trustedCertificates addObject:(__bridge_transfer id )(certificate)];

//trustedCertificates = @[CFBridgingRelease(certificate)];

//注意:這里將之前導入的證書設置成下面驗證的Trust Object的anchor certificate

SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)trustedCertificates);

//2)SecTrustEvaluate會查找前面SecTrustSetAnchorCertificates設置的證書或者系統(tǒng)默認提供的證書,對trust進行驗證

OSStatus status = SecTrustEvaluate(trust, &result);

if (status == errSecSuccess &&

(result == kSecTrustResultProceed ||

result == kSecTrustResultUnspecified)){

return YES;

}

return NO;

}

```

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末免钻,一起剝皮案震驚了整個濱河市彼水,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌极舔,老刑警劉巖凤覆,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拆魏,居然都是意外死亡盯桦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門渤刃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拥峦,“玉大人,你說我怎么就攤上這事卖子÷院牛” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵洋闽,是天一觀的道長玄柠。 經(jīng)常有香客問我,道長诫舅,這世上最難降的妖魔是什么羽利? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮刊懈,結果婚禮上这弧,老公的妹妹穿的比我還像新娘。我一直安慰自己虚汛,他們只是感情好匾浪,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卷哩,像睡著了一般户矢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上殉疼,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天梯浪,我揣著相機與錄音,去河邊找鬼瓢娜。 笑死挂洛,一個胖子當著我的面吹牛,可吹牛的內容都是我干的眠砾。 我是一名探鬼主播虏劲,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了柒巫?” 一聲冷哼從身側響起励堡,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎堡掏,沒想到半個月后应结,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡泉唁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年鹅龄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亭畜。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡扮休,死狀恐怖,靈堂內的尸體忽然破棺而出拴鸵,到底是詐尸還是另有隱情玷坠,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布劲藐,位于F島的核電站八堡,受9級特大地震影響,放射性物質發(fā)生泄漏瘩燥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一不同、第九天 我趴在偏房一處隱蔽的房頂上張望厉膀。 院中可真熱鬧,春花似錦二拐、人聲如沸服鹅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽企软。三九已至,卻和暖如春饭望,著一層夾襖步出監(jiān)牢的瞬間仗哨,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工铅辞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厌漂,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓斟珊,卻偏偏與公主長得像苇倡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內容