web-dev-qa-db-fra.com

Problèmes liés à l'épinglage SSL et à AFNetworking 2.5.0 (erreur NSURLErrorDomain -1012.)

Nous avons eu du mal à sécuriser les connexions réseau de notre application avec SSL avec AFNetworking 2.5.0.

Nous utilisons une autorité de certification auto-signée et avons mis en œuvre une politique de sécurité personnalisée à l'aide de certificats épinglés.

Nous avons testé pas mal de configurations fournies par AFNetworking mais nous n’avons pas eu de chance jusqu’à présent. Le message d'erreur que nous recevons est le suivant:

2015-01-05 19: 03: 07.191 AppName [9301: 319051] Erreur lors de la mise à jour de l'utilisateur périple. Erreur: Domaine d'erreur = Code NSURLErrorDomain = -1012 "L'opération N'a pas pu être terminée. (Erreur NSURLErrorDomain -1012.)" UserInfo = 0x7ae056b0 {NSErrorFailingURLKey = https://api.XXX.com/XXX/XXX/ , NSErrorFailingURLStringKey = https://api.XXX.com/XXX/XXX/ }

Notre certificat fonctionne bien sur d'autres clients tels que cURL et Android. Lorsque vous utilisez HTTP, notre implémentation fonctionne parfaitement.

Quelqu'un est-il au courant de problèmes liés aux certificats épinglés et à AFNetworking? Si oui, nous apprécierions les indications que vous pourriez avoir.

Voici une partie de la mise en œuvre:

+ (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 sharedApplication] setNetworkActivityIndicatorVisible:YES];
   AFHTTPRequestOperationManager *manager = [HttpClient customHttpRequestOperationManager];
   manager.responseSerializer = [AFHTTPResponseSerializer serializer];
   [manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
       [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
       success(operation, responseObject);
   } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
       [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
       failure(operation, error);
   }];
}

Je vous remercie!

32
davhab

Après avoir lu le code AFNetworking et vérifié les journaux des modifications, voici ce que je devais faire pour que cela fonctionne.

Créez votre objet AFSecurityPolicy avec AFSSLPinningModeCertificate:

AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

Par défaut, AFNetworking validera le nom de domaine du certificat. Nos certificats sont générés serveur par serveur et ne portent pas tous un nom de domaine. Nous devons donc le désactiver:

[policy setValidatesDomainName:NO];

Les certificats étant auto-signés, ils sont techniquement "non valides", nous devons donc également l'autoriser:

[policy setAllowInvalidCertificates:YES];

Enfin, AFNetworking tentera de valider le certificat tout au long de la chaîne de certificats, ce qui me semblerait que cela ne ferait que remonter dans notre chaîne vers notre autorité de certification, mais pour une raison quelconque, ce n'est pas le cas, nous devons donc également le désactiver:

[policy setValidatesCertificateChain:NO];

Et c'est tout! Définissez la stratégie de sécurité dans votre gestionnaire de demandes comme vous le faites déjà et cela devrait fonctionner correctement.

Donc, récapitulons, tout ce que vous avez vraiment besoin de changer dans le code que vous avez posté est le suivant:

A) Comme David Caunt mentionné, changez votre mode d'épingler de AFSSLPinningModeNone à AFSSLPinningModeCertificate 

et

B) Ajoutez la ligne pour désactiver la validation du nom de domaine: [policy setValidatesDomainName:NO]

Autre remarque, AFNetworking recherche désormais automatiquement les fichiers .cer dans votre bundle. Ainsi, si vous souhaitez renommer votre certificat avec une extension .cer, vous pouvez supprimer le code permettant d'extraire les données de certificat de l'ensemble et de définir les certificats épinglés.

46
Jordan Bondo

depuis que vous avez initialisé le gestionnaire, vous pouvez faire:

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

et cela fonctionnera pour un certificat auto-signé

24
Even Cheng

Je recevais cette erreur, Error Domain=NSURLErrorDomain Code=-1012 NSErrorFailingURLStringKey

Le changement ci-dessous à lui seul l'a fait fonctionner pour moi.

self.validatesDomainName = NO;
5
thatzprem

Vous créez une AFSecurityPolicy avec SSLPinningMode mode AFSSLPinningModeNone

Pour que AFNetworking fasse confiance au serveur, lorsque le mode d'épinglage est défini sur AFSSLPinningModeNone, vous devez définir allowInvalidCertificates sur YES, mais il s'agit du contraire de ce que vous essayez d'atteindre.

Au lieu de cela, vous devez créer votre stratégie de sécurité avec le mode d'épingler AFSSLPinningModeCertificate ou AFSSLPinningModePublicKey:

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
3
David Snabel-Caunt
- (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;
}

Cela a fonctionné pour moi pour une raison quelconque. Vous ne savez toujours pas en quoi cela change les choses car d'autres connexions de mon application fonctionnent sans prendre toutes ces mesures.

Voici à quoi ressemble la politique de sécurité générant des erreurs -

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

Maintenant, s'en tenir à la règle "Ne pas réparer si ce n'est pas cassé"

1
genaks

Si vous souhaitez simplement faire taire l'avertissement sans disposer d'un certificat client, la stratégie doit ressembler à ceci:

AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
[policy setValidatesDomainName:YES];
[policy setAllowInvalidCertificates:NO];
0
thomas gotzsche

Pour moi, j'avais use_frameworks! défini dans ma Podfile - le projet n'engendre pas l'utilisateur de Swift et j'utilisais Pods pour AFNetworking. Commenter cela a résolu le problème pour moi. 

0
Robert J. Clegg

Après avoir traité un problème similaire, il est courant que les choses semblent normales via les connexions HTTPS du navigateur, car de nombreux navigateurs mettent en cache les fichiers de certificat de tiers afin qu’ils ne soient pas toujours chargés. Par conséquent, il se peut très bien que votre chaîne de certificats ne soit pas totalement fiable, comme vous l’auriez peut-être laissé croire. 

En d'autres termes, il peut sembler intéressant de se connecter en toute sécurité avec un navigateur, mais en fonction de vos paramètres AFNetworking, votre application n'acceptera pas votre chaîne de certificats. Une fois que vous êtes sûr que vos paramètres sont appropriés, vous devez vous assurer que votre chaîne de certificats est aussi performante que vous le pensez. Téléchargez une application appelée SSL Detective et interrogez votre serveur. Vous pouvez également utiliser www.ssldecoder.org . Assurez-vous qu'il n'y a pas d'objets rouges (non fiables) dans votre chaîne. S'il y en a, changez la configuration de votre cert sur le serveur.

Étant donné que vos paramètres AFNetworking sont les suivants:

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

Il se peut que votre chaîne de certificats n’aime pas votre chaîne car elle est auto-signée. Vous devrez peut-être également passer à OUI. 

0
Marcel