2010-09-22 12 views
18

estoy recibiendo este errorIgnorar errores de certificado con NSURLConnection

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 solucionar este problema?

yo probamos este código:

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

pero cuando me siento EXC_BAD_ACCESS en el método didReceiveResponse.

+0

* "errores de certificado Ignorar con NSURLConnection" * - es mejor para solucionar el problema en lugar de ignorar el error. Si no va a utilizar PKI y SSL correctamente, ¿por qué usarlo? – jww

Respuesta

1

¿Está utilizando 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.

16

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

Esencialmente desea definir una interfaz ficticia justo por encima del @implementation:

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

Y antes de llamar sendSynchronousRequest, invoque el método privado que ha definido en la interfaz ficticia:

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

Este enlace usa API privada y al usar eso, ¿mi aplicación puede ser rechazada por Apple? Si es así, no puedo usarlo porque tengo que poner mi aplicación en la tienda de aplicaciones. ¿Alguna otra forma de hacerlo? – Ideveloper

+0

Creo que esta publicación respondió con precisión a su pregunta: http://stackoverflow.com/questions/933331/how-to-use-nsurlconnection-to-connect-with-ssl-for-an-untrusted-cert/2033823#2033823 –

+0

No, eso no funciona. Hace que se llame primero a CertainRecieveResponse antes del método canAuthenticateAgainstProtectionSpace y su bloqueo en el método didRecieveResponse. – Ideveloper

3

Usted' Establezca el delegado como propio, para que pueda solucionarlo implementando parte de NSURLConnectionDelegate en la clase que envía esa solicitud.

Implementar esto:

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

Al hacer esto:

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 

Nota: esto no es una solución para utilizar en la producción. ¡Los certificados existen por una razón! :)

2

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 esperaba. 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 Technical Note TN2232 HTTPS Server Trust Evaluation de Apple. kSecTrustResultUnspecified es un éxito, vea 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]; 
} 
15

El (en desuso no, no privado) forma correcta, utilizando el nuevo:

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

método que Apple ha especificado debe ser utilizado para NSURLConnectionDelegates es responder al método ServerTrust con la credencial que era proporciona el espacio de protección (esto le permitirá conectar: ​​

- (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 es llamado varias veces, una vez para cada meto autenticación disponibles d, si usted no desea iniciar sesión con que el uso del método:

[challenge.sender rejectProtectionSpaceAndContinueWithChallenge:challenge]; 
5

tuve problema similar. Lo tengo resuelto mediante el uso de abajo 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 están en desuso los métodos siguientes:

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space { ... } 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { ... } 
+1

Esto es bueno, pero no maneja una [CA que * no * está precargada] (https://support.apple.com/en-us/HT204132) ni que el usuario agregue a la tienda. Pero el uso de la lista de CA precargada es peligroso, ya que cualquier CA del CA Zoo puede afirmar que certifica el sitio (incluso los incorrectos, como los que emiten certificados para la interceptación). Creo que es mejor especificar la CA que se supone que certifica el sitio, por lo que las CA's malas no pueden romper el canal. – jww

Cuestiones relacionadas