每次调用NSURLAuthenticationMethodServerTrust挑战

时间:2014-03-15 07:43:31

标签: ios https

情况:我正在构建一个企业应用程序,可用于共享图片等。它正在使用HTTP,现在我转移到HTTPS,因为它是公开的。我在App中捆绑了客户端证书(.cer)。

我已经在这里和Eskimo在AppDev论坛(https://devforums.apple.com/message/737087#737087)和此处(http://www.techrepublic.com/blog/software-engineer/use-https-certificate-handling-to-protect-your-ios-app/)上进行了大部分讨论和帖子。但我的问题是我的应用程序有多次调用同一个HTTPS服务器,每次我都会收到NSURLAuthenticationMethodServerTrust挑战。这是正常的吗?对于每次挑战,我都会失去接近4秒的交易时间,而且我的照片需要一段时间才能加载。

另外,请参阅NSURLAuthenticationMethodDefault挑战IF条件评论,真的不确定为什么会这样。

总结一下。 1.我是否必须检查证书并验证每次HTTPS呼叫? 2.如果我放入IF块,为什么验证质询(NSURLAuthenticationMethodDefault)不起作用。

任何帮助都将不胜感激。

-(BOOL) shouldTrustProtectionSpace:(NSURLProtectionSpace *) protectionSpace{

    NSString *certPath = [[NSBundle mainBundle] pathForResource:@"file.something.com" ofType:@"cer"];
    NSData   *certData = [[NSData alloc] initWithContentsOfFile:certPath];
    CFDataRef certDataRef = (__bridge_retained CFDataRef)certData;
    SecCertificateRef cert = SecCertificateCreateWithData(NULL,certDataRef);

    CFArrayRef certArrayRef = CFArrayCreate(NULL, (void *)&cert,1,NULL);
    SecTrustRef serverTrust =  protectionSpace.serverTrust;
    SecTrustSetAnchorCertificates(serverTrust, certArrayRef);


    SecTrustResultType trustResult;
    SecTrustEvaluate(serverTrust, &trustResult);

    if ( trustResult == kSecTrustResultRecoverableTrustFailure){

        NSLog(@"kSecTrustResultRecoverableTrustFailure");
        CFDataRef errDataRef = SecTrustCopyExceptions(serverTrust);
        SecTrustSetExceptions(serverTrust, errDataRef);

        SecTrustEvaluate(serverTrust, &trustResult);

    }

    if ( trustResult == kSecTrustResultUnspecified){
        NSLog(@"In Trust: kSecTrustResultUnspecified");
    }

    if ( trustResult == kSecTrustResultProceed){
        NSLog(@"In Trust: kSecTrustResultProceed");
    }


    return trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed;

}

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{

    NSLog(@"didReceiveChallenge");




    if ([self shouldTrustProtectionSpace:[challenge protectionSpace]]) {


        SecTrustRef trust = [[challenge protectionSpace] serverTrust];
        SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, 0);

        NSData *serverCertificateData = (__bridge NSData *)SecCertificateCopyData(certificate);


        NSURL *bundledCertURL = [[NSBundle mainBundle] URLForResource:@"file.something.com" withExtension:@"cer"];
        NSData *bundledCertData = [[NSData alloc] initWithContentsOfURL:bundledCertURL];

        BOOL whatWeExpected = [serverCertificateData isEqual:bundledCertData];


        if (whatWeExpected == TRUE ){

            NSLog(@"As Expected");

            NSURLCredential *cred = [[NSURLCredential alloc] initWithTrust:trust];
            [[challenge sender] useCredential:cred forAuthenticationChallenge:challenge];

        }

    }

    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodDefault]) {

        NSLog(@"NSURLAuthenticationMethodDefault");

    }



    //This piece of code I put it outside the above IF for now else I never get
    //the NSURLAuthenticationMethodDefault challenge?????

    NSURLCredential *newCredential;
    newCredential = [NSURLCredential credentialWithUser:userName
                                               password:passWord
                                            persistence:NSURLCredentialPersistenceNone];
    completionHandler(NSURLSessionAuthChallengeUseCredential, newCredential);


}

0 个答案:

没有答案