Подтвердить что ты не робот

Проблемы с SSL-подключением и AFNetworking 2.5.0 (ошибка NSURLErrorDomain -1012.)

У нас было трудное время, чтобы обеспечить сетевые подключения приложений с помощью SSL с помощью AFNetworking 2.5.0.

Мы используем самозаверяющий центр сертификации и внедряем настраиваемую политику безопасности с помощью закрепленных сертификатов.

Мы проверили немало конфигураций, предоставленных AFNetworking, но пока не повезло. Получаем сообщение об ошибке:

2015-01-05 19: 03: 07.191 AppName [9301: 319051] Ошибка при обновлении пользователя поездка. Ошибка: Ошибка домена = NSURLErrorDomain Code = -1012 "операция не может быть завершена. (Ошибка NSURLErrorDomain -1012.)" UserInfo = 0x7ae056b0 {NSErrorFailingURLKey = https://api.XXX.com/XXX/XXX/, NSErrorFailingURLStringKey = https://api.XXX.com/XXX/XXX/}

Наш сертификат отлично работает на других клиентах, таких как cURL и Android. При использовании HTTP наша реализация также отлично работает.

Кто-нибудь знает о каких-либо проблемах, связанных с закрепленными сертификатами и AFNetworking? Если да, вы оцените любые указатели, которые у вас могут быть.

Здесь часть реализации:

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

Спасибо!

4b9b3361

Ответ 1

После прочтения кода AFNetworking и проверки журналов изменений, здесь я должен был сделать это, чтобы это работало.

Создайте свой объект AFSecurityPolicy с помощью AFSSLPinningModeCertificate:

AFSecurityPolicy* policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

По умолчанию AFNetworking будет проверять доменное имя сертификата. Наши сертификаты создаются на основе каждого сервера, и не все из них будут иметь доменное имя, поэтому нам необходимо отключить это:

[policy setValidatesDomainName:NO];

Поскольку сертификаты самоподписаны, они технически "недействительны", поэтому нам также необходимо это сделать:

[policy setAllowInvalidCertificates:YES];

Наконец, AFNetworking будет пытаться проверить сертификат по всей цепочке сертификатов, что для меня кажется, что он будет только подниматься по цепочке в НАШ СА, но по какой-либо причине это не так, поэтому нам нужно отключить это тоже:

[policy setValidatesCertificateChain:NO];

И это! Задайте политику безопасности в диспетчере запросов, как вы уже делали, и она должна работать нормально.

Итак, recap, все, что вам действительно нужно изменить в коде, который вы опубликовали, это:

A) Как упоминалось Дэвид Каунт, измените режим пиннинга с AFSSLPinningModeNone на AFSSLPinningModeCertificate

и

B) Добавьте строку, чтобы отключить проверку имени домена: [policy setValidatesDomainName:NO]

Еще одно замечание: AFNetworking теперь автоматически проверяет ваш пакет для файлов .cer, поэтому, если вы хотите переименовать свой сертификат для расширения .cer, вы можете исключить код, чтобы получить данные сертификата из комплекта и установить закрепленные сертификаты.

Ответ 2

так как вы инициализируетесь менеджером, вы можете сделать:

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

и он будет работать для самозаверяющего сертификата

Ответ 3

Я получал эту ошибку, Error Domain=NSURLErrorDomain Code=-1012 NSErrorFailingURLStringKey

Только одно изменение помогло мне работать.

self.validatesDomainName = NO;

Ответ 4

Вы создаете AFSecurityPolicy с SSLPinningMode mode AFSSLPinningModeNone.

Для AFNetworking доверять серверу, с режим установлен на AFSSLPinningModeNone прижав, вы должны установить allowInvalidCertificates в YES, но это противоположно тому, что вы пытаетесь достичь.

Вместо этого вы должны создать свою политику безопасности в режиме пиннинга AFSSLPinningModeCertificate или AFSSLPinningModePublicKey:

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

Ответ 5

Имея дело с аналогичной проблемой, обычным явлением кажется обычное соединение с браузером HTTPS, так как многие браузеры хранят файлы сертификатов кешей от третьих сторон, так что их не всегда нужно загружать. Поэтому вполне может быть, что ваша цепочка сертификатов не полностью доверена, поскольку вам, возможно, повезло.

Другими словами, может показаться, что можно надежно подключиться к браузеру, но в зависимости от ваших настроек AFNetworking ваше приложение фактически не примет вашу цепочку сертификатов. После того, как вы уверены, что ваши настройки подходят, следующий шаг - убедиться, что ваша цепочка сертификатов на самом деле так хороша, как вы думаете. Загрузите приложение под названием SSL Detective и запросите свой сервер. Вы также можете использовать www.ssldecoder.org. Убедитесь, что в цепочке нет красных (ненадежных) предметов. Если есть, измените настройки своего сертификата на сервере.

Учитывая, что ваши настройки AFNetworking следующие:

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

Возможно, вам не нравится ваша цепочка сертификатов, потому что она сама подписана. Возможно, вам также придется переключить их на YES.

Ответ 6

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

Это сработало для меня по какой-то причине. Все еще не уверен, как это меняет ситуацию, потому что другие подключения в моем приложении работают без принятия всех этих шагов.

Вот что выглядит политика безопасности, создающая ошибки -

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

Теперь придерживаться правила "Не исправить, если оно не нарушено"

Ответ 7

Для меня у меня use_frameworks! установлен в моем Podfile - проект не делает пользователя Swift, и я использовал Pods для AFNetworking. Комментируя это, исправил проблему для меня.

Ответ 8

Я пробовал все это, но ничего не помог, тогда я искал эту строку

'NSLog (@ "Чтобы проверить доменное имя для самоподписанных сертификатов, вы ДОЛЖНЫ использовать пиннинг." );

и ниже этой строки я изменил

'return NO;'
до

'return YES;'

и он сделал магию.

Спасибо.