我收到此错误
The certificate for this server is invalid. You might be connecting to a server
that is pretending to be "server addres goes here" which could put your
confidential information at risk."
我正在使用这种方法:
[NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
我该如何解决这个问题?
我试过这段代码:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self];
然后我在didReceiveResponse方法中获得了EXC_BAD_ACCESS。
答案 0 :(得分:17)
如果您没有发送任何敏感信息,则可以忽略无效证书。 This article描述了如何做到这一点。以下是Alexandre Colucci针对该文章中描述的方法之一的示例实现。
基本上你想在@implementation
:
@interface NSURLRequest (DummyInterface)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host;
+ (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host;
@end
在调用sendSynchronousRequest
之前,调用在虚拟接口中定义的私有方法:
[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[URL host]];
答案 1 :(得分:16)
使用新的正确(非弃用,非私人)方式:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
Apple已指定的方法应该用于NSURLConnectionDelegates是使用为保护空间提供的凭据来响应ServerTrust方法(这将允许您连接:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
{
NSLog(@"Ignoring SSL");
SecTrustRef trust = challenge.protectionSpace.serverTrust;
NSURLCredential *cred;
cred = [NSURLCredential credentialForTrust:trust];
[challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
return;
}
// Provide your regular login credential if needed...
}
如果您不想使用该方法登录,则此方法会针对每种可用的身份验证方法多次调用一次:
[challenge.sender rejectProtectionSpaceAndContinueWithChallenge:challenge];
答案 2 :(得分:5)
我有类似的问题。通过使用下面的代码片段来解决它:
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSLog(@"This will execute successfully!");
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust) {
[[challenge sender] useCredential:[NSURLCredential credentialForTrust:[[challenge protectionSpace] serverTrust]] forAuthenticationChallenge:challenge];
}
}
由于以下方法已被弃用:
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space { ... }
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { ... }
答案 3 :(得分:3)
您已将委托设置为self,因此您可以通过在发送该请求的类中实现NSURLConnectionDelegate的一部分来解决此问题。
实施这个:
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
通过这样做:
[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
注意:这不是在生产中使用的解决方案。证书存在是有原因的! :)
答案 4 :(得分:3)
这不符合您的“如何忽略错误”的问题。这是不负责任的。
相反,它向您展示了如何加载证明服务器的CA,以便连接可以按预期进行。下面,CA与应用程序捆绑在一起,称为ca-cert.der
。它是DER(而不是PEM)编码的证书。
另外,您可能想看一下Apple的Technical Note TN2232 HTTPS Server Trust Evaluation。 kSecTrustResultUnspecified
成功,请参阅Technical Q&A QA1360 Describing the kSecTrustResultUnspecified error。
-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:
(NSURLProtectionSpace*)space
{
return [[space authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:
(NSURLAuthenticationChallenge *)challenge
{
if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust])
{
do
{
SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
NSCAssert(serverTrust != nil, @"serverTrust is nil");
if(nil == serverTrust)
break; /* failed */
NSData* caCert = [NSData dataWithContentsOfFile:@"ca-cert.der"];
NSCAssert(caCert != nil, @"caCert is nil");
if(nil == caCert)
break; /* failed */
SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);
NSCAssert(caRef != nil, @"caRef is nil");
if(nil == caRef)
break; /* failed */
NSArray* caArray = [NSArray arrayWithObject:(__bridge id)(caRef)];
NSCAssert(caArray != nil, @"caArray is nil");
if(nil == caArray)
break; /* failed */
OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);
NSCAssert(errSecSuccess == status, @"SecTrustSetAnchorCertificates failed");
if(!(errSecSuccess == status))
break; /* failed */
SecTrustResultType result = -1;
status = SecTrustEvaluate(serverTrust, &result);
if(!(errSecSuccess == status))
break; /* failed */
NSLog(@"Result: %d", result);
/* This test looks for a "SUCCESS" */
/* kSecTrustResultUnspecified and kSecTrustResultProceed are success */
if(result != kSecTrustResultUnspecified && result != kSecTrustResultProceed)
break; /* failed */
#if 0
/* Alternate test looks for a "NOT FAILURE" */
/* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success */
/* since the user will likely tap-through to see the dancing bunnies */
if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)
break; /* failed to trust cert (good in this case) */
#endif
// The only good exit point
return [[challenge sender] useCredential: [NSURLCredential credentialForTrust: serverTrust]
forAuthenticationChallenge: challenge];
} while(0);
}
// Bad dog
return [[challenge sender] cancelAuthenticationChallenge: challenge];
}
答案 5 :(得分:1)
您使用的是HTTPS网址吗?如果是这样,请转到浏览器中的URL并检查证书。确保证书对您尝试使用的域或子域有效,并且已在服务器上安装了所有中间证书。我遇到了与此类似的问题,解决方案是安装中间证书。