双向认证第二步: p.12文件进行ssl双向认证

时间:2022-05-18 19:42:25

将上一章创建好的client.p12拖进新建的工程

在ViewController.m文件中

- (void)viewDidLoad {

[super viewDidLoad];

// 请求数据

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];

NSURL *url = [NSURL URLWithString:@”https://www.zhuangzhuangyong.com“];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];

[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

[request setHTTPShouldHandleCookies:NO];

[request setTimeoutInterval:30];

[request setHTTPMethod:@”GET”];

NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

NSString *message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@”%@”, message);

}];

[task resume];

}

#pragma mark - NSURLSessionDelegate

- (void)URLSession:(NSURLSession )session didReceiveChallenge:(NSURLAuthenticationChallenge )challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler

{

NSString *method = challenge.protectionSpace.authenticationMethod;

NSLog(@”%s,,,\nmethod==%@”,func, method);

//客户端验证服务器端

if([method isEqualToString:NSURLAuthenticationMethodServerTrust]){

NSString *host = challenge.protectionSpace.host;

NSLog(@”%s,,,,,\nhost==%@”,func, host);

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

completionHandler(NSURLSessionAuthChallengeUseCredential, credential);

return;

}

//服务器验证客户端

if ([method 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);

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

completionHandler(NSURLSessionAuthChallengeUseCredential, credential);

}

}

#pragma mark - Private method

/**

* @brief 解密证书

*

* @param inP12Data 证书数据

* @param identity

*

* @return 32 字节 错误码

*/

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

OSStatus securityError = errSecSuccess;

CFStringRef password = CFSTR(“123456”);

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;

}

控制台输出

It works!