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)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容