2010-09-22 1 views
18

sto ottenendo questo erroreIgnorare gli errori del certificato 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." 

Sto usando questo metodo:

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

Come posso risolvere questo problema?

Ho provato questo codice:

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

ma tanto sono EXC_BAD_ACCESS nel metodo didReceiveResponse.

+0

* "gli errori del certificato Ignorando con NSURLConnection" * - il suo meglio per risolvere il problema piuttosto che ignorare l'errore. Se non hai intenzione di usare correttamente PKI e SSL, allora perché usarlo del tutto? – jww

risposta

1

Si sta utilizzando un URL HTTPS. Se è così, vai all'URL in un browser e controlla il certificato. Assicurarsi che il certificato sia valido per il dominio o il dominio secondario che si sta tentando di utilizzare e che tutti i certificati intermedi siano stati installati sul server. Ho avuto un problema simile a questo e la soluzione era installare i certificati intermedi.

16

Si può semplicemente ignorare il certificato non valido se non si inviano informazioni sensibili. This article descrive come è possibile farlo. Ecco un'implementazione di esempio di Alexandre Colucci per uno dei metodi descritti in tale articolo.

In sostanza si vuole definire un'interfaccia fittizia appena sopra il @implementation:

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

E prima di chiamare sendSynchronousRequest, richiamare il metodo privato definito nell'interfaccia dummy:

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

Questo link utilizza API private e utilizzando la mia app viene rifiutata da Apple? Se è così allora non posso usarlo perché devo mettere la mia app su appstore. Qualche altro modo per farlo? – Ideveloper

+0

Penso che questo post abbia risposto esattamente alla tua domanda: http://stackoverflow.com/questions/933331/how-to-use-nsurlconnection-to-connect-with-ssl-for-an-untrusted-cert/2033823#2033823 –

+0

No, questo non funzionavaRecevi cheRecieve venga richiamato prima del metodo canAuthenticateAgainstProtectionSpace e il suo arresto anomalo nel metodo didRecieveResponse. – Ideveloper

3

You' abbiamo impostato il delegato come auto, in modo da poterlo risolvere implementando parte di NSURLConnectionDelegate nella classe che invia quella richiesta.

Implementare questo:

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

In questo modo:

[challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge]; 

Nota: questa non è una soluzione da utilizzare in produzione. I certificati esistono per una ragione! :)

2

Questo non risponde alla domanda "come ignorare gli errori". Questo è irresponsabile.

Piuttosto, mostra come caricare la CA che certifica il server in modo che la connessione possa procedere come previsto. Sotto, la CA è fornita in bundle con l'app e si chiama ca-cert.der. È un certificato codificato DER (al contrario di PEM).

Inoltre, si potrebbe voler dare un'occhiata a Technical Note TN2232 HTTPS Server Trust Evaluation di Apple. kSecTrustResultUnspecified è successo, vedere 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

La (non deprecato, non privato) modo corretto utilizzando il nuovo:

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

metodo che Apple ha specificato deve essere utilizzato per NSURLConnectionDelegates è quello di rispondere al metodo ServerTrust con la credenziale che era previsto per lo spazio di protezione (questo vi permetterà di collegare:

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

questo metodo viene chiamato più volte, una volta per ogni metho di autenticazione disponibile d, se non si desidera accedere utilizzando tale metodo utilizzare:

[challenge.sender rejectProtectionSpaceAndContinueWithChallenge:challenge]; 
5

Ho avuto problemi simili. Got it risolto utilizzando seguito frammento di codice:

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

Dal metodi indicati sono obsoleti:

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

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

Questo è buono, ma non gestisce un [CA che * non * precaricato] (https://support.apple.com/en-us/HT204132) o aggiunto al negozio dall'utente. Tuttavia, l'utilizzo dell'elenco CA precaricato è pericoloso poiché qualsiasi CA nello Zoo CA può richiedere di certificare il sito (anche quelli errati, come quelli che emettono certificati per l'intercettazione). Penso sia meglio specificare la CA che dovrebbe certificare il sito in modo che CA non valide possano rompere il canale. – jww