iOS 5: https (ASIHTTPRequest) перестает работать

#objective-c #ios5 #https #asihttprequest #ssl

#objective-c #ios5 #https #asihttprequest #ssl

Вопрос:

У меня есть приложение, которое использует ASIHTTPRequest.

Я перекомпилировал свое приложение с iOS 5 (sdk: 5.0 / xcode: 4.2 Сборка 4D199), и соединения https завершаются ошибкой с сообщением об ошибке (тот же вызов с отключенным https работает нормально):

 Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred" UserInfo=0xa8e66e0 {NSUnderlyingError=0xa8ac6c0 "The operation couldn’t be completed. (OSStatus error -9844.)", NSLocalizedDescription=A connection failure occurred}
  

С включенным журналом отладки:

 [STATUS] Starting asynchronous request <ASIFormDataRequest: 0xd96fc00>

[CONNECTION] Request <ASIFormDataRequest: 0xd96fc00> will not use a persistent connection

[STATUS] Request <ASIFormDataRequest: 0xd96fc00>: Failed

[CONNECTION] Request #(null) failed and will invalidate connection #(null)
  

Я нашел этот связанный пост:
https://devforums.apple.com/message/537440#537440
что может объяснить мою проблему.

исходя из идеи, что iOS 5 предпочитает протокол TLS 1.2, я пытаюсь изменить параметр kCFStreamSocketSecurityLevelTLSv1 в AIHTTPRequest.m

   NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
                                     [NSNumber numberWithBool:YES],
kCFStreamSSLAllowsExpiredCertificates,
                                     [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                                     [NSNumber numberWithBool:NO],  kCFStreamSSLValidatesCertificateChain,
                                     kCFNull,kCFStreamSSLPeerName,
                                      kCFStreamSocketSecurityLevelTLSv1, kCFStreamSSLLevel,// my modif
                                     nil];
  

безуспешно. Может быть, моя модификация неверна?

Подробные сведения:

  • Я отключил ARC
  • Я использую libz.1.2.5.dylib
  • Я обновил ASIHTTPRequest неделю назад.

Я не знаю, является ли проблема историей сертификата (например, версией TLS) или чем-то еще.

любая помощь / идея приветствуется!

Ответ №1:

Вот окончательное решение:

https://developer.apple.com/library/ios/#technotes/tn2287/_index.html#//apple_ref/doc/uid/DTS40011309

         NSDictionary *sslProperties = [[NSDictionary alloc] initWithObjectsAndKeys:
                                       [NSNumber numberWithBool:YES], kCFStreamSSLAllowsExpiredCertificates,
                                       [NSNumber numberWithBool:YES], kCFStreamSSLAllowsAnyRoot,
                                       [NSNumber numberWithBool:NO],  kCFStreamSSLValidatesCertificateChain,
                                       kCFNull,kCFStreamSSLPeerName,
                                       @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
                                       nil];
  

Добавление этого параметра:

                                        @"kCFStreamSocketSecurityLevelTLSv1_0SSLv3", kCFStreamSSLLevel,
  

Комментарии:

1. Смотрите также этот патч: github.com/ignaval/asi-http-request/commit /… — вы также хотите добавить свойство в регистр validateCertificate=YES

2. Для меня также потребовалось изменение @ckhan, прежде чем оно заработало на 5.0

3. принудительно kCFStreamSocketSecurityLevelTLSv1_2 работает и с этим методом

Ответ №2:

В нашей настройке проблема была устранена путем вставки

 [sslProperties setObject:(NSString *)kCFStreamSocketSecurityLevelSSLv3 forKey:(NSString *)kCFStreamSSLLevel];
  

чуть выше

 CFReadStreamSetProperty((CFReadStreamRef)[self readStream], kCFStreamPropertySSLSettings, sslProperties);
  

в разделе Настройки SSL-сертификата.

РЕДАКТИРОВАТЬ: в соответствии с http://developer.apple.com/library/ios/#technotes/tn2287/_index.html#//apple_ref/doc/uid/DTS40011309 следующее должно быть более надежным

 [sslProperties setObject:@"kCFStreamSocketSecurityLevelTLSv1_0SSLv3" forKey:(NSString *)kCFStreamSSLLevel];
  

Комментарии:

1. Спасибо за решение. Это работает для моего приложения для iPhone, но когда я добавляю ту же строку в свой iPad ASIHTTPRequest, она не работает. Каким может быть возможное решение? Спасибо. 🙂

2. Поскольку я ответил на этот вопрос, ASI перестал поддерживать ASIHTTPRequest, и я начал использовать AFNetworking github.com/AFNetworking/AFNetworking .

Ответ №3:

похоже, что ASIHTTPRequest отменяется. и в текущей версии возникла проблема с iOS 5.

http://groups.google.com/group/asihttprequest/browse_thread/thread/7731197dbe71c260

они рекомендуют перейти на NSURLConnection.

Ответ №4:

Это то, что я бы попробовал:

  1. Загрузите свежую копию asihttprequest, поместите ее во вновь созданное очень простое приложение, которое просто использует один http, и посмотрите, ведет ли оно себя так же
  2. Попробуйте с другими серверами https, посмотрите, получите ли вы такое же поведение (попробуйте с некоторыми известными, например https://twitter.com — linkedin, google и т.д., у всех тоже есть версии https)
  3. Попробуйте использовать тот же сервер в Safari (все еще на устройстве iOS)

Как бы то ни было, у меня есть ASIHTTPRequest на iOS5, который отлично работает с https-серверами моего клиента — мне не нужно было вносить какие-либо изменения для iOS5.

Комментарии:

1. спасибо за советы. # 1: никаких изменений; # 2: другая веб-страница работает нормально. ; # 3: в родном браузере страница отображается так, как ожидалось. ; Не могли бы вы быть достаточно любезны, чтобы сообщить мне версию TLS, которую использует сервер вашего клиента при вызове из вашего приложения?

2. Честно говоря, я не уверен; вы знаете, как я бы проверил? Судя по имеющимся данным, похоже, что это та же проблема TLSv1.2, что и ссылка, которую вы разместили на форумах Apple — возможно, вам следует опубликовать там свой код и надеяться, что Куинн сможет взглянуть?

3. как я и опасался, и, как вы предположили, это может быть проблема, связанная с сервером. Итак, я не уверен, как я могу задать этот вопрос на форуме (NDA). В любом случае, если проблема связана с версией TLS, почему моя модификация не устраняет ее ?… В любом случае, спасибо за помощь, я рад узнать, что это не общая проблема с ASIHTTPRequest / iOS5.

Ответ №5:

Попробуйте использовать kCFStreamSocketSecurityLevelSSLv3 вместо TLSv1. Это сработало для меня, когда я столкнулся с подобной ситуацией. Я не уверен, почему автоматическое согласование не возвращается к правильному протоколу, но, по крайней мере, на некоторых серверах, похоже, происходит сбой при ASIHTTPRequest, где он будет работать с NSURLConnection.