iOS, 使用自签名证书https请求,(NSURLSession)

来源:互联网 发布:数据结构与算法张小莉 编辑:程序博客网 时间:2024/04/28 11:14

上篇说到了已经完成服务端环境搭建, 并且完成了测试。 

  这里来倒腾一下iOS端, 这里使用的类为NSURLSession,  网上很多代码, 发现大多都有问题。 无法正常使用。

把client.p12导入进入项目,添加测试代码

    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]     delegate:self delegateQueue:[NSOperationQueue mainQueue]];        NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://192.168.3.210:8443/dynamicWebProject/login/map.form"]     completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);    }];        [task resume];

实现NSURLSessionDelegate,

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

这里主要完成的就是证书的操作。


- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{    NSLog(@"didReceiveChallenge ");    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {        NSLog(@"server ---------");//        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];        NSString *host = challenge.protectionSpace.host;        NSLog(@"%@", host);                NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];                        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);    }    else if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodClientCertificate])    {        //客户端证书认证        //TODO:设置客户端证书认证        // load cert        NSLog(@"client");        NSString *path = [[NSBundle mainBundle]pathForResource:@"client"ofType:@"p12"];        NSData *p12data = [NSData dataWithContentsOfFile:path];        CFDataRef inP12data = (__bridge CFDataRef)p12data;        SecIdentityRef myIdentity;        OSStatus status = [self extractIdentity:inP12data toIdentity:&myIdentity];        if (status != 0) {            return;        }        SecCertificateRef myCertificate;        SecIdentityCopyCertificate(myIdentity, &myCertificate);        const void *certs[] = { myCertificate };        CFArrayRef certsArray =CFArrayCreate(NULL, certs,1,NULL);        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];//        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];//         网上很多错误代码如上,正确的为:            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);    }}- (OSStatus)extractIdentity:(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;    }    else    {        NSLog(@"clinet.p12 error!");    }        if (options) {        CFRelease(options);    }    return securityError;}

亲测代码能正常运行。 

0 0
原创粉丝点击