iOS自签名证书https请求(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;  
}

参考:http://blog.csdn.net/zhdzxc123/article/details/53927842

你可能感兴趣的:(iOS自签名证书https请求(NSURLSession))