2008-08-18 10 views
8

Usando NSURLRequest, estoy intentando acceder a un sitio web que tiene un certificado caducado. Cuando envío de la solicitud, mi conexión : didFailWithError método delegado se invoca con la siguiente información:Objective-C/Cocoa: ¿Cómo acepto un certificado de servidor incorrecto?

-1203, NSURLErrorDomain, bad server certificate 

Mis búsquedas sólo han aparecido una solución: un método de clase oculta en NSURLRequest:

[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:myHost]; 

Sin embargo, no quiero usar API privadas en una aplicación de producción por razones obvias.

¿Alguna sugerencia sobre qué hacer? ¿Debo utilizar las API de CFNetwork? De ser así, dos preguntas:

  • ¿Algún código de muestra que pueda usar para comenzar? No he encontrado ninguno en línea.
  • Si utilizo CFNetwork para esto, ¿debo abandonar NSURL por completo?

EDIT:

iPhone OS 3.0 introdujo un método admitido para hacer esto. Más detalles aquí: How to use NSURLConnection to connect with SSL for an untrusted cert?

Respuesta

1

He llegado al mismo problema: estaba desarrollando un cliente SOAP, y el servidor de desarrollo tiene un certificado "local". No pude resolver el problema ni siquiera con ese método, ya que no estaba usando NSURL, sino los métodos de WS (pobremente documentados y aparentemente abandonados) y, por el momento, decidí (internamente) usar un sistema que no sea SSL. conexión.

Dicho esto, sin embargo, la pregunta que viene a la mente es, si no está dispuesto a usar una API privada en una aplicación de producción, ¿debería permitir el acceso a un sitio con un certificado dudoso?

Cito Jens Alfke:

Eso no es sólo un problema de seguridad teórico. Algo como
como el 25% de los servidores DNS públicos se han visto comprometidos, según
informes recientes, y puede dirigir a los usuarios a sitios de phishing/malware/anuncios incluso
si ingresan el nombre de dominio correctamente. Lo único que lo protege
es la comprobación de certificados SSL.

+0

El sitio en cuestión es en nuestro entorno de pruebas, sólo se puede acceder internamente. Supongo que los administradores de red son demasiado baratos o perezosos para mantener certificados válidos para ello. Nuestro entorno de producción tiene un certificado válido, por supuesto. Como esta característica de esquivar certificados no se habilitaría o necesitaría en producción, podría usar la API privada solo para probar. Todavía preferiría hacerlo de la manera "correcta", ya que estaría de regreso en la casilla uno si alguna vez extrajeran la API privada. –

1

¿Se puede crear un certificado firmado y añadir su autoridad de certificación personalizada a la CA de confianza? No estoy muy seguro de cómo funcionaría en el iPhone, pero supongo que en Mac OS X deberías agregarlos al llavero.

Usted también podría estar interesado en este post Re: How to handle bad certificate error in NSURLDownload

3

Si es para un servidor interno para propósitos de prueba, ¿por qué no importar el certificado del servidor de prueba en el llavero y establecer la configuración personalizada de confianza?

8

La forma admitida de hacerlo requiere el uso de CFNetwork.Tienes que hacer es adjuntar un kCFStreamPropertySSLSettings a la corriente que especifica kCFStreamSSLValidatesCertificateChain == kCFBooleanFalse. A continuación se muestra un código rápido que lo hace, menos la comprobación de resultados válidos y la limpieza. Una vez que haya hecho esto, puede usar CFReadStreamRead() para obtener los datos.

CFURLRef myURL = CFURLCreateWithString(kCFAllocatorDefault, CFSTR("http://www.apple.com"), NULL); 
CFHTTPMessageRef myRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, CFSTR("GET"), myURL, kCFHTTPVersion1_1); 
CFReadStreamRef myStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, myRequest); 
CFMutableDictionaryRef myDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
CFDictionarySetValue(myDict, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse); 
CFReadStreamSetProperty(myStream, kCFStreamPropertySSLSettings, myDict);  
CFReadStreamOpen(myStream); 
0

Otra opción sería utilizar una biblioteca de conexiones alternativa.

Soy un gran fan de AsyncSocket y tiene soporte para auto firmado CERT

http://code.google.com/p/cocoaasyncsocket/

echar un vistazo, creo que es la forma más robusta entonces los NSURLRequests estándar.

Cuestiones relacionadas