Problemas con SSL Pinning y AFNetworking 2.5.0 (error NSURLErrorDomain -1012.)

Hemos estado teniendo dificultades para asegurar las conexiones de networking de nuestra aplicación con SSL utilizando AFNetworking 2.5.0.

Utilizamos una autoridad de certificación autofirmada e implementamos una política de security personalizada usando certificates fijados.

Hemos probado bastantes configuraciones proporcionadas por AFNetworking pero hasta ahora no hemos tenido suerte. El post de error que recibimos es:

2015-01-05 19: 03: 07.191 AppName [9301: 319051] Error al actualizar el viaje del usuario. Error: Error de dominio = NSURLErrorDomain Code = -1012 "La operación no se pudo completar. (NSURLErrorDomain error -1012.)" UserInfo = 0x7ae056b0 {NSErrorFailingURLKey = https://api.XXX.com/XXX/XXX/ , NSErrorFailingURLStringKey = https://api.xxx.com/XXX/XXX/ }

Nuestro certificate funciona bien en otros clientes como cURL y Android. Cuando utilizamos HTTP, nuestra implementación funciona perfectamente también.

¿Alguien está al tanto de cualquier problema relacionado con los certificates prendidos y AFNetworking? En caso afirmativo, agradeceríamos cualquier indicador que pueda tener.

Aquí hay una parte de la implementación:

+ (AFSecurityPolicy*)customSecurityPolicy { AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"der"]; NSData *certData = [NSData dataWithContentsOfFile:cerPath]; [securityPolicy setAllowInvalidCertificates:NO]; [securityPolicy setValidatesCertificateChain:NO]; [securityPolicy setPinnedCertificates:@[certData]]; return securityPolicy; } + (AFHTTPRequestOperationManager*)customHttpRequestOperationManager { AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.securityPolicy = [self customSecurityPolicy]; // SSL return manager; } +(void)getRequestWithUrl:(NSString*)url success:(void(^)(AFHTTPRequestOperation *operation, id responseObject))success failure:(void(^) (AFHTTPRequestOperation *operation, NSError *error))failure { [[UIApplication shanetworkingApplication] setNetworkActivityIndicatorVisible:YES]; AFHTTPRequestOperationManager *manager = [HttpClient customHttpRequestOperationManager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { [[UIApplication shanetworkingApplication] setNetworkActivityIndicatorVisible:NO]; success(operation, responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { [[UIApplication shanetworkingApplication] setNetworkActivityIndicatorVisible:NO]; failure(operation, error); }]; } 

¡Gracias!

Después de leer el código de AFNetworking y verificar los loggings de cambios, esto es lo que tuve que hacer para que esto funcione.

Cree su object AFSecurityPolicy con AFSSLPinningModeCertificate:

 AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; 

De forma pnetworkingeterminada, AFNetworking validará el nombre de dominio del certificate. Nuestros certificates se generan por server, y no todos tendrán un nombre de dominio, por lo que debemos deshabilitarlo:

 [policy setValidatesDomainName:NO]; 

Dado que los certificates están autofirmados, son técnicamente "no válidos", por lo que debemos permitirlo también:

 [policy setAllowInvalidCertificates:YES]; 

Por último, AFNetworking intentará validar el certificate hasta el final de la cadena de certificates, lo que para mí parece que solo iría a la cadena a NUESTRA CA, pero por la razón que sea que no, así que también tenemos que deshabilitarla:

 [policy setValidatesCertificateChain:NO]; 

¡Y eso es! Establezca la política de security en su administrador de requestes como ya lo está haciendo y debería funcionar bien.

Entonces, recapitulando, todo lo que necesitas cambiar en el código que publicaste es este:

A) Como mencionó David Caunt , cambie su modo de fijación de AFSSLPinningModeNone a AFSSLPinningModeCertificate

y

B) Agregue la línea para deshabilitar la validation del nombre de dominio: [policy setValidatesDomainName:NO]

Otra nota, AFNetworking ahora verifica automáticamente su package para files .cer, por lo que si cambiara el nombre de su certificate para tener una extensión .cer, puede eliminar el código para get los datos del certificate del package y establecer los certificates fijados.

ya que tiene el administrador inicializado, puede hacer lo siguiente:

 manager.securityPolicy.allowInvalidCertificates = YES; manager.securityPolicy.validatesDomainName = NO; 

y funcionará para un certificate autofirmado

Error Domain=NSURLErrorDomain Code=-1012 NSErrorFailingURLStringKey este error, Error Domain=NSURLErrorDomain Code=-1012 NSErrorFailingURLStringKey

El siguiente cambio por sí solo me funcionó.

 self.validatesDomainName = NO; 

Está creando una AFSecurityPolicy con SSLPinningMode mode AFSSLPinningModeNone .

Para que AFNetworking confíe en el server, con el modo de fijación establecido en AFSSLPinningModeNone , debe establecer allowInvalidCertificates en YES , pero esto es lo contrario de lo que está intentando lograr.

En su lugar, debe crear su política de security con el modo de fijación AFSSLPinningModeCertificate o AFSSLPinningModePublicKey :

 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; 

Después de haber abordado un problema similar, es común que las cosas parezcan normales a través de las conexiones HTTPS del browser, ya que muchos browseres almacenan files de certificates de terceros, de modo que no siempre necesitan cargarse. Por lo tanto, bien podría ser que su cadena de certificates no sea totalmente confiable, como es posible que se haya hecho creer.

En otras palabras, puede parecer correcto conectarse de forma segura con un browser, pero dependiendo de la configuration de AFNetworking, su aplicación no aceptará su cadena de certificates. Una vez que esté seguro de que su configuration es adecuada, el siguiente paso es asegurarse de que su cadena de certificates sea realmente tan buena como cree que es. Descarga una aplicación llamada SSL Detective y consulta tu server. También puede usar http://www.ssldecoder.org . Asegúrese de que no haya elementos rojos (no confiables) en su cadena. Si los hay, cambie su configuration cert en el server.

Dado que su configuration de AFNetworking es la siguiente:

  [securityPolicy setAllowInvalidCertificates:NO]; [securityPolicy setValidatesCertificateChain:NO]; 

Puede que no le guste la cadena de certificates porque está autografiada. Es posible que también tenga que cambiarlos a SÍ.

 - (AFSecurityPolicy *)securityPolicy { NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"*.something.co.in" ofType:@"cer"]; NSData *certData = [NSData dataWithContentsOfFile:cerPath]; AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; [securityPolicy setAllowInvalidCertificates:YES]; [securityPolicy setPinnedCertificates:@[certData]]; [securityPolicy setValidatesDomainName:NO]; [securityPolicy setValidatesCertificateChain:NO]; return securityPolicy; } 

Esto funcionó para mí por alguna razón. Aún no estoy seguro de cómo esto cambia las cosas porque otras conexiones en mi aplicación funcionan sin seguir todos estos pasos.

Así es como se ve la política de security de generación de errores:

 - (AFSecurityPolicy *)securityPolicy { NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"*.something.co.in" ofType:@"cer"]; NSData *certData = [NSData dataWithContentsOfFile:cerPath]; AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; [securityPolicy setAllowInvalidCertificates:NO]; [securityPolicy setPinnedCertificates:@[certData]]; [securityPolicy setValidatesDomainName:YES]; return securityPolicy; } 

Ahora se adhieren a la regla "No arregles si no está rota".

¡Para mí, he use_frameworks! configurado en mi Podfile : el proyecto no convierte al usuario de Swift y estaba usando Pods para AFNetworking . Comentando esto, arregló el problema para mí.

Probé todos estos pero nada ayudó, entonces busqué esta línea

'NSLog (@ "Para validar un nombre de dominio para certificates autofirmados, DEBE usar la fijación.");'

y debajo de esta línea cambié

'devuelve NO;'
a

'devuelve SÍ';

y hizo la magia.

Gracias.