Ignorar errores de certificado con NSURLConnection

Estoy recibiendo este error

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." 

Estoy usando este método:

 [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 

¿Cómo puedo arreglar esto?

Intenté este código:

  NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 

pero luego obtengo EXC_BAD_ACCESS en el método didReceiveResponse.

Simplemente podría ignorar el certificado inválido si no está enviando información confidencial. Este artículo describe cómo puedes hacer eso. Aquí hay una implementación de ejemplo de Alexandre Colucci para uno de los métodos descritos en ese artículo.

Básicamente, desea definir una interfaz ficticia justo arriba de @implementation :

 @interface NSURLRequest (DummyInterface) + (BOOL)allowsAnyHTTPSCertificateForHost:(NSString*)host; + (void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString*)host; @end 

Y antes de llamar a sendSynchronousRequest , invoque el método privado que definió en la interfaz ficticia:

 [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[URL host]]; 

La forma correcta (no desaprobada, no privada) de usar el nuevo:

 - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 

El método que apple ha especificado debe usarse para NSURLConnectionDelegates es responder al método ServerTrust con la credencial que se proporcionó para el espacio de protección (esto le permitirá conectarse:

 - (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... } 

Este método se llama varias veces una vez por cada método de autenticación disponible, si no quieres iniciar sesión con ese método, utiliza:

  [challenge.sender rejectProtectionSpaceAndContinueWithChallenge:challenge]; 

Tuve un problema similar. Lo solucionó usando el siguiente fragmento de código:

 -(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]; } } 

Dado que los siguientes métodos están en desuso:

 - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space { ... } - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { ... } 

Ha configurado el delegado como uno mismo, por lo que puede solucionarlo implementando parte de NSURLConnectionDelegate en la clase que envía esa solicitud.

Implementa esto:

 -(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; 

Al hacer esto:

 [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 

Nota: esta NO es una solución para usar en producción. ¡Los certificados existen por una razón! 🙂

Esto no responde a su pregunta de “cómo ignorar los errores”. Eso es ser irresponsable.

Más bien, le muestra cómo cargar la CA que certifica el servidor para que la conexión pueda continuar como se espera. A continuación, la CA se incluye con la aplicación y se llama ca-cert.der . Es un certificado codificado DER (a diferencia de PEM).

Además, es posible que desee echar un vistazo a la Evaluación de Confianza del Servidor HTTPS de la Nota Técnica TN2232 de Apple. kSecTrustResultUnspecified es kSecTrustResultUnspecified , ver Technical Q & A QA1360 Describiendo el error kSecTrustResultUnspecified .

 -(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]; } 

¿Estás usando una url HTTPS? Si es así, vaya a la url en un navegador y verifique el certificado. Asegúrese de que el certificado sea válido para el dominio o subdominio que está tratando de usar, y que todos los certificados intermedios se hayan instalado en su servidor. Tuve un problema similar a esto, y la solución fue instalar los certificados intermedios.