Tengo el siguiente código simple para conectarse a una página web SSL

NSMutableURLRequest *urlRequest=[NSMutableURLRequest requestWithURL:url];
[ NSURLConnection sendSynchronousRequest: urlRequest returningResponse: nil error: &error ];

Excepto que da un error si el cert es un auto firmado un Error Domain=NSURLErrorDomain Code=-1202 UserInfo=0xd29930 "untrusted server certificate". hay una forma de configurarlo para que acepte conexiones de todos modos (igual que en un navegador puede pulsar aceptar) o una manera de evitar esto?

InformationsquelleAutor erotsppa | 2009-06-01

13 Comentarios

  1. 415

    Hay una API compatible para el logro de esto! Agregar algo como esto a su NSURLConnection delegado:

    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
      return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
      if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
        if ([trustedHosts containsObject:challenge.protectionSpace.host])
          [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    
      [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
    }

    Nota que connection:didReceiveAuthenticationChallenge: puede enviar su mensaje de desafío.remitente (mucho) más tarde, después de presentar un cuadro de diálogo al usuario si es necesario, etc.

    • Muchas gracias, funciona perfectamente. Acaba de quitar el los dos ifs y mantener sólo el useCendential parte en la didReceiveAuthentificationChallenge de devolución de llamada si desea aceptar cualquier sitio https.
    • Esto es impresionante! Sin embargo, sólo funciona en el iPhone y 10.6. Hay un trabajo similar-alrededor de 10.5?
    • Alguna idea sobre cómo enviar una autentica credencial (creado con «credentialWithUser») junto con este «credentialForTrust» credencial? Específicamente… stackoverflow.com/questions/2949640/…
    • ¿qué es un trustedHosts, donde n ¿cómo es el objeto definido
    • Ameya, sería un NSArray de NSString objetos. Las cadenas son los nombres de host como @»google.com».
    • Este código funciona bien. Pero tenga en cuenta que el punto de tener toda certificados válidos es para evitar que el hombre-en-el-medio de los ataques. Por lo tanto, si usted utiliza este código, alguien puede suplantar el llamado «host de confianza». Usted todavía obtener los datos de las características de cifrado de SSL, pero perderás el host identificar las características de validación.
    • Tenga en cuenta que, sin código adicional, este enfoque también se echa en contra de la validez de certificados.
    • Para aquellos que utilizan Gowalla del AFNetworking de la biblioteca, usted puede conseguir esta característica por pegar ese código en la parte inferior de la AFURLConnectionOperation.m
    • Funciona bien. Acaba de agregar el dominio a mi servidor a la trustedServers matriz y bang. Curiosamente el problema surgió solamente en el iPhone 3G
    • cómo puede ser aplicado con sendAsynchronousRequest (como no podemos establecer un delegado para que uno)?
    • Sólo quiero timbre en que estos métodos de delegado no se les llama en el sendSynchronous método de clase. Ver: enlace
    • Estos métodos son ahora consideradas como obsoletas como de iOS 5.0 y Mac OS X 10.6. El -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge método debe utilizarse en su lugar.
    • cierto, pero los métodos más antiguos todavía se llama «Si la conexión:willSendRequestForAuthenticationchallenge: no está implementado, los más viejos, obsoletos métodos de conexión:canAuthenticateAgainstProtectionspace: conexión:didReceiveAuthenticationChallenge:, y de la conexión:didCancelAuthenticationChallenge: son llamados en su lugar.»
    • Me rodean este tipo de código con #ifdef DEBUG/#endif para que no acabe en la producción. Sería bueno ver una versión que funciona con la no-código obsoleto.
    • Si estoy usando [NSURLConnection sendSynchronousRequest:petición] ¿cómo puedo lograr el mismo resultado? No es posible cambiar a asincrónica ahora.
    • cuadro de diálogo estás hablando..es que «la conexión no es segura» o «certificado válido»…por Favor me ayude como quiere la validación de certificado en mi iOS código.Donde debo colocar ese cuadro de diálogo en – (void)conexión:(NSURLConnection *)conexión didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)desafío {
    • Cuando puedo añadir que la línea de dos errores, uno de ellos dijo que se espera ver (y otro diciendo que espera ver ). Usted dijo que la voy a agregar a la NSURLRequest delegado, pero sólo tengo el delegado para el proyecto en sí, estoy algo confuso aquí?
    • Parece que tienes que añadir una «- » al principio de ese método, y un cuerpo vacío.
    • Esto no ayuda si estás tratando de usar MPMoviePlayerController. Yo no tengo ningún problema en el simulador, pero no funciona en el iPhone sí mismo.
    • Hay una solución para aquellos que utilizan el método de clase a +sendAsync…?
    • He implementado el delegado métodos, pero ¿por qué no hay que ser llamado?
    • puede ser que usted olvidó poner el NSURLConnection delegado
    • Aunque esto funciona, pero a veces falla. Es bastante raro. Todos los que delegar método se llama igual que cuando funciona, pero tengo «El certificado para este servidor no es válido. Usted podría estar conectados a un servidor que está pretendiendo ser «mysite.com» que podría poner su información confidencial en riesgo.» He utilizado NSURLConnection +sendAsynchronousRequest:queue:completionHandler: método. Alguna idea?
    • Solucionado, Parece NSURLConnection +sendAsynchronousRequest:queue:completionHandler: no funciona bien cuando nos saltamos el certificado de verificación (en -connection:willSendRequestForAuthenticationChallenge: NSURLConnection método delegado). Sospecho que es el uso de NSOperationQueue que rompe el flujo. Solución: cambiar a la configuración NSURLConnection con BlocksKit y llame a -start manualmente, ahora funciona perfectamente.
    • Esta respuesta sólo funciona para las solicitudes asincrónicas. Si el uso de sendSynchronousRequest: en su lugar, usted querrá ver la parte superior de votación respuesta aquí: stackoverflow.com/questions/3766755/…
    • Funciona a la perfección para NSURLConnection. Algún consejo para NSURLSession?
    • Es indended que en caso de que ambas condiciones son satsified que estás haciendo tanto useCredential y continueWithoutCredential…?

  2. 36

    Si no quieren (o no pueden) para uso privado Api, hay un código abierto (licencia BSD) biblioteca llamada ASIHTTPRequest que proporciona una envoltura alrededor de la parte baja de nivel CFNetwork APIs. Recientemente se introdujo la posibilidad de permitir HTTPS connections el uso de auto-firmado o que no son de confianza certificados con el -setValidatesSecureCertificate: de la API. Si no quieres tirar en toda la biblioteca, puede utilizar la fuente como referencia para la implementación de la misma funcionalidad a ti mismo.

    • Tim, usted puede encontrar el deseo de uso de async, por otras razones, de todos modos (como ser capaz de mostrar una barra de progreso), me parece que para todos, pero la más simple de las solicitudes que esa es la forma en que me vaya. Así que tal vez usted sólo debe implementar Async ahora y ahorre la molestia más tarde.
    • Ver esto por la aplicación (pero el uso de [r setValidatesSecureCertificate:NO]; ): stackoverflow.com/questions/7657786/…
    • Lo siento que me trajo a este tema de la copia de seguridad. Pero desde el iOS 5 introdujo el ARCO de características. ¿Cómo puedo hacer este trabajo ahora?
    • Lai Ver stackoverflow.com/a/6658549/300972
    • ASIHTTPRequest de desarrollo de la biblioteca ha sido abandonado.
    • Podría usted por favor revise este: stackoverflow.com/q/56627757/1364053

  3. 33

    Idealmente, debería ser sólo dos escenarios de cuando una aplicación de iOS tendría que aceptar un certificado de confianza.

    Escenario: el usuario está conectado a un entorno de prueba que es el uso de un certificado auto-firmado.

    Escenario B: Usted es el Proxy HTTPS tráfico a través de un MITM Proxy like Burp Suite, Fiddler, OWASP ZAP, etc. Los Proxies devolverá un certificado firmado por un auto-firmado CA de manera que el proxy es capaz de capturar HTTPS de tráfico.

    La producción de los ejércitos nunca debe usar la onu-certificados de confianza para razones obvias.

    Si usted necesita tener el simulador de iOS aceptar un certificado de confianza para propósitos de prueba se recomienda que no cambie la lógica de la aplicación en el fin de desactivar la integrada en la validación de certificados proporcionados por el NSURLConnection Api. Si la aplicación es lanzada al público sin la eliminación de esta lógica, será susceptible de hombre-en-el-medio de los ataques.

    La forma recomendada para aceptar la onu-certificados de confianza para propósitos de prueba es para importar el Certificado de la Autoridad de certificados(CA) que ha firmado el certificado en el Simulador de iOS o dispositivo iOS. Me escribió una rápida entrada de blog que muestra cómo hacer esto que un Simulador de iOS en:

    la aceptación de certificados que no son de confianza utilizando el simulador de ios

    • Impresionante cosas de hombre. Estoy de acuerdo, es tan fácil olvidarse de la desactivación de este especial de la lógica de la aplicación a aceptar cualquier certificado no es de confianza.
    • «Idealmente, debería ser sólo dos escenarios de cuando una aplicación de iOS tendría que aceptar un certificado de confianza.» – ¿Acerca de rechazar un ‘afirmó’ buena certificado cuando fijación de un certificado? Conferir: Dignotar (pwn d) y Trustwave (MitM la fama).
    • Totalmente de acuerdo con su declaración sobre el olvido quitar el código. La ironía es que es mucho más fácil hacer este cambio en el código que conseguir que el simulador para aceptar la auto-firmado certs.
  4. 12

    NSURLRequest tiene un método privado llamado setAllowsAnyHTTPSCertificate:forHost:, que va a hacer exactamente lo que te gustaría. Se podría definir el allowsAnyHTTPSCertificateForHost: método en NSURLRequest a través de una categoría, y configurarlo para volver YES para el host que desea reemplazar.

    • Habitual advertencias acerca de indocumentados Api de aplicar… pero es bueno saber que es posible.
    • Sí, absolutamente. He añadido otra respuesta que no implican el uso privado de las APIs.
    • Funciona cuando se utiliza «NSURLConnection sendSynchronousRequest:»?
    • sí, así es, con este código: stackoverflow.com/a/7422992/59198
  5. 11

    Para complementar el aceptado respuesta, mucho mejor de seguridad, usted podría agregar su certificado de servidor o de su propio certificado de CA raíz para llavero( https://stackoverflow.com/a/9941559/1432048), sin embargo, haciendo esto por sí solo no hará que NSURLConnection autenticar su auto-firmado el servidor automáticamente. Usted todavía tiene que agregar el siguiente código a su NSURLConnection delegado, copiado de Apple código de ejemplo AdvancedURLConnections, y hay que añadir dos archivos(Credenciales.h, las Credenciales.m) de apple código de ejemplo para sus proyectos.

    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
    }
    - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
    //       if ([trustedHosts containsObject:challenge.protectionSpace.host])
    OSStatus                err;
    NSURLProtectionSpace *  protectionSpace;
    SecTrustRef             trust;
    SecTrustResultType      trustResult;
    BOOL                    trusted;
    protectionSpace = [challenge protectionSpace];
    assert(protectionSpace != nil);
    trust = [protectionSpace serverTrust];
    assert(trust != NULL);
    err = SecTrustEvaluate(trust, &trustResult);
    trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
    //If that fails, apply our certificates as anchors and see if that helps.
    //
    //It's perfectly acceptable to apply all of our certificates to the SecTrust
    //object, and let the SecTrust object sort out the mess.  Of course, this assumes
    //that the user trusts all certificates equally in all situations, which is implicit
    //in our user interface; you could provide a more sophisticated user interface
    //to allow the user to trust certain certificates for certain sites and so on).
    if ( ! trusted ) {
    err = SecTrustSetAnchorCertificates(trust, (CFArrayRef) [Credentials sharedCredentials].certificates);
    if (err == noErr) {
    err = SecTrustEvaluate(trust, &trustResult);
    }
    trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified));
    }
    if(trusted)
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
    }
  6. 10

    No puedo tomar ningún crédito por ello, pero esto que yo he encontrado funcionó muy bien para mis necesidades. shouldAllowSelfSignedCert es mi BOOL variable. Sólo tiene que añadir a su NSURLConnection delegado y debe ser rockin para una rápida derivación en cada conexión.

    - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)space {
    if([[space authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
    if(shouldAllowSelfSignedCert) {
    return YES; //Self-signed cert will be accepted
    } else {
    return NO;  //Self-signed cert will be rejected
    }
    //Note: it doesn't seem to matter what you return for a proper SSL cert
    //      only self-signed certs
    }
    //If no other authentication is required, return NO for everything else
    //Otherwise maybe YES for NSURLAuthenticationMethodDefault and etc.
    return NO;
    }
  7. 10

    En iOS 9, conexiones SSL, se producirá un error para todos válidos o certificados autofirmados. Este es el comportamiento predeterminado de la nueva Aplicación De Seguridad En El Transporte característica en iOS 9.0 o posterior, y en OS X 10.11 y más tarde.

    Puede invalidar este comportamiento en el Info.plist, mediante el establecimiento de NSAllowsArbitraryLoads a YES en el NSAppTransportSecurity diccionario. Sin embargo, recomiendo reemplazar esta configuración para propósitos de prueba solamente.

    Cómo utilizar NSURLConnection para conectar con SSL para una confianza del cert?

    Para información, consulte Aplicación de Transporte de la Nota técnica aquí.

    • La única solución que funcionó para mí, no tengo manera de cambiar la base avanzada de marco a la suite de mis necesidades, que solucionado, gracias!
    • Ahora he visto que Google pide NSAllowArbitraryLoads = YES para Admob (en base avanzada). firebase.google.com/docs/admob/ios/ios9
  8. 6

    La categoría de solución publicado por Nathan de Vries pasará a la AppStore privado de la API de cheques, y es útil en los casos donde no se tiene el control de la NSUrlConnection objeto.
    Un ejemplo es NSXMLParser que va a abrir la dirección URL de suministro, pero no exponga el NSURLRequest o NSURLConnection.

    En iOS 4 la solución todavía parece funcionar, pero sólo en el dispositivo, el Simulador no invocar la allowsAnyHTTPSCertificateForHost: método más.

  9. 6

    Tienes que utilizar NSURLConnectionDelegate para permitir las conexiones HTTPS y hay nuevas devoluciones de llamada con iOS8.

    En desuso:

    connection:canAuthenticateAgainstProtectionSpace:
    connection:didCancelAuthenticationChallenge:
    connection:didReceiveAuthenticationChallenge:

    Lugar de aquellos, deberá declarar:

    connectionShouldUseCredentialStorage: – Enviados para determinar si la dirección URL del cargador debe usar el almacenamiento de credenciales para la autenticación de la conexión.

    connection:willSendRequestForAuthenticationChallenge: – Le dice al delegado que la conexión se envía una petición de autenticación por desafío.

    Con willSendRequestForAuthenticationChallenge puede utilizar challenge como hizo con los obsoletos métodos, por ejemplo:

    //Trusting and not trusting connection to host: Self-signed certificate
    [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
  10. 3

    He publicado algunos gist código (basado en el trabajo de alguien más que se me nota), que permite autenticar adecuadamente contra un auto certificado generado (y cómo obtener un certificado de que – ver los comentarios de la parte inferior de Cocoanetics)

    Mi código es aquí github

  11. 2

    Si quieres seguir usando sendSynchronousRequest yo trabajo en esta solución:

    FailCertificateDelegate *fcd=[[FailCertificateDelegate alloc] init];
    NSURLConnection *c=[[NSURLConnection alloc] initWithRequest:request delegate:fcd startImmediately:NO];
    [c setDelegateQueue:[[NSOperationQueue alloc] init]];
    [c start];    
    NSData *d=[fcd getData];

    se puede ver aquí: Objective-C SSL Conexión Síncrona

  12. 1

    Con AFNetworking he logrado consumido https webservice con el código de abajo,

    NSString *aStrServerUrl = WS_URL;
    //Initialize AFHTTPRequestOperationManager...
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    [manager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    manager.securityPolicy.allowInvalidCertificates = YES; 
    [manager POST:aStrServerUrl parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
    successBlock(operation, responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
    errorBlock(operation, error);
    }];
  13. 1

    Puede utilizar este Código

    -(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
    {
    if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodServerTrust)
    {
    [[challenge sender] useCredential:[NSURLCredential credentialForTrust:[[challenge protectionSpace] serverTrust]] forAuthenticationChallenge:challenge];
    }
    }

    Uso -connection:willSendRequestForAuthenticationChallenge: en lugar de estos Obsoletos Métodos

    En desuso:

    -(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace  
    -(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 
    -(void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

Dejar respuesta

Please enter your comment!
Please enter your name here