情况:我正在构建一个企业应用程序,可用于共享图片等。它正在使用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);
}