[iOS]网络请求中的证书验证-NSURLSession

记录一下在网络请求中证书验证的基于NSURLSession的实现

一.开始一个请求

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.data = [NSMutableData data];
    
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://XXXXXXXXX"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:240];
    [request setHTTPMethod:@"POST"];
    [request setHTTPShouldHandleCookies:YES];
    NSStringEncoding gbkEncoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSData *postData = [@"XXX=XXX&XXX=XXX" dataUsingEncoding:gbkEncoding];
    [request setHTTPBody:postData];
   
    [[self.session dataTaskWithRequest:request] resume];
}

二.实现NSURLConnection验证的回调方法

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {
    // 如果是请求证书信任,我们再来处理,其他的不需要处理
    if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
    
        SecTrustRef trust = challenge.protectionSpace.serverTrust;
        
        //获取本地证书
        NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"XXX" ofType:@"cer"]];
        
        SecTrustResultType result;
        SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(data));
        
        SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)@[CFBridgingRelease(certificate)]);
    
        NSURLCredential *cred = [NSURLCredential credentialForTrust:trust];
    
        OSStatus status = SecTrustEvaluate(trust, &result);
    
    
        if (status == errSecSuccess &&
            (result == kSecTrustResultProceed ||
             result == kSecTrustResultUnspecified)) {
                
                //验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接

                // 调用block
                completionHandler(NSURLSessionAuthChallengeUseCredential,cred);
            } else {
                
                //验证失败,取消这次验证流程

                completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, cred);
            }
    }
}

三.接收数据

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [self.data appendData:data];
}

四.处理数据

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSString *retStr = [[NSString alloc] initWithData:self.data encoding:enc];
    NSLog(@"retString:%@",retStr);
    NSData* newData=[retStr dataUsingEncoding:NSUTF8StringEncoding];
    id responseObject = [NSJSONSerialization JSONObjectWithData:newData options:NSJSONReadingMutableLeaves error:&error];
    if (error) {
        NSLog(@"error:%@",error);
    } else {
        NSLog(@"%@", responseObject);
    }
}

推荐阅读更多精彩内容

  • 目录 网络基本概念 TCP/IP协议簇基本概念 HTTP 网络开发技术解决方案 数据解析 网络优化 1. 网络基本...
    Ryan___阅读 334评论 1 0
  • 在苹果彻底弃用NSURLConnection之后自己总结的一个网上的内容,加上自己写的小Demo,很多都是借鉴网络...
    付寒宇阅读 3,195评论 2 14
  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 1,644评论 0 5
  • 在 WWDC 16 中,Apple 表示, 从 2017年1月1日起(最新消息, 实施时间已延期),所有新提交的 ...
    kmplayer阅读 676评论 0 5
  • 收集自互联网 README.md,md是markdown的缩写。 Markdown是一种轻量级标记语言,它以纯文本...
    Zhang21阅读 5,086评论 0 3