CFNetwork SSLHandshake не удалось iOS 9
Кто-нибудь с iOS 9 beta 1 столкнулся с этой проблемой?
Я использую стандартное соединение NSURLConnection для подключения к веб-сервису, и как только вызов выполняется в webservice, я получаю следующую ошибку. В настоящее время это работает в iOS 8.3
Возможная бета-ошибка? любые идеи или мысли были бы замечательными! Я знаю его очень рано в разработке iOS 9
Вот полная ошибка:
Ошибка CFNetwork SSLHandshake (-9824) NSURLSession/NSURLConnection Ошибка загрузки HTTP (kCFStreamErrorDomainSSL, -9824)
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://mywebserviceurl"]];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
Ответы
Ответ 1
iOS 9 и OSX 10.11 требуют TLSv1.2 SSL для всех хостов, на которых вы планируете запрашивать данные, если только вы не укажете домены исключений в вашем файле Info.plist приложения.
Синтаксис конфигурации Info.plist выглядит следующим образом:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow insecure HTTP requests-->
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
Если вашему приложению (например, стороннему веб-браузеру) требуется подключиться к произвольным хостам, вы можете настроить его следующим образом:
<key>NSAppTransportSecurity</key>
<dict>
<!--Connect to anything (this is probably BAD)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Если вам нужно это сделать, лучше всего обновить свои серверы для использования TLSv1.2 и SSL, если они этого еще не сделали. Это следует рассматривать как временное решение.
На сегодняшний день предварительная документация никоим образом не упоминает об этих параметрах конфигурации. Как только это произойдет, я обновлю ответ на ссылку на соответствующую документацию.
Ответ 2
** ВАЖНОЕ ПРИМЕЧАНИЕ ДЛЯ iOS 10 BETA: **
В iOS 10 строка TLS ДОЛЖНА иметь форму "TLSv1.0". Это не может быть просто "1.0". Да, это невероятно глупо и непринужденно. Добро пожаловать в развитие iOS.
Следующая комбинация приведенных выше рекомендаций работает.
Предположим, вы пытаетесь подключиться к хосту (YOUR_HOST.COM), который имеет только TLS 1.0.
Добавьте их в свое приложение Info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>YOUR_HOST.COM</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
</dict>
Ответ 3
Дополнительная информация Конфигурирование исключений безопасности для транспорта приложений в iOS 9 и OSX 10.11
Любопытно, что вы заметите, что соединение пытается изменить http-протокол https для защиты от ошибок в вашем коде, где вы случайно ошибочно настроили URL. В некоторых случаях это может на самом деле работать, но его также запутывает.
Эта отправка приложения с защитой приложений на транспорте содержит некоторые полезные советы по отладке
Сбой ATS
Большинство сбоев ATS будут отображаться как CFErrors с кодом в -9800 серии. Они определены в заголовке Security/SecureTransport.h
2015-08-23 06:34:42.700 SelfSignedServerATSTest[3792:683731] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
CFNETWORK_DIAGNOSTICS
Установите переменную среды CFNETWORK_DIAGNOSTICS в 1, чтобы получить дополнительную информацию о консоли о сбое
nscurl
Инструмент будет работать через несколько различных комбинаций ATS исключения, попытки безопасного подключения к данному узлу при каждом ATS и сообщать результат.
nscurl --ats-diagnostics https://example.com
Ответ 4
Если ваш бэкэнд использует безопасное соединение ant, вы получаете использование NSURLSession
CFNetwork SSLHandshake failed (-9801)
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)
вам нужно проверить конфигурацию вашего сервера, особенно, чтобы получить версию ATS и сертификат SSL. Info:
Вместо Разрешить небезопасное подключение, установив NSExceptionAllowsInsecureHTTPLoads = YES
, вместо этого вам нужно Разрешить пониженную безопасность, если ваш сервер не соответствует минимальному требованию (v1.2 ) для ATS (или лучше исправить серверную сторону).
Предоставление пониженной безопасности одному серверу
<key>NSExceptionDomains</key>
<dict>
<key>api.yourDomaine.com</key>
<dict>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
используйте клиент openssl для исследования сертификата и получения конфигурации сервера с помощью клиента openssl:
openssl s_client -connect api.yourDomaine.com:port //(you may need to specify port or to try with https://... or www.)
.. найти в конце
SSL-Session:
Protocol : TLSv1
Cipher : AES256-SHA
Session-ID: //
Session-ID-ctx:
Master-Key: //
Key-Arg : None
Start Time: 1449693038
Timeout : 300 (sec)
Verify return code: 0 (ok)
Безопасность транспорта приложений (ATS) требует версии протокола безопасности транспортного уровня (TLS) версии 1.2.
Требования для подключения с использованием ATS:
Требования к соединению веб-службы для использования безопасности приложений (ATS) включают сервер, шифры соединений и сертификаты, а именно:
Сертификаты должны быть подписаны одним из следующих типов ключей:
Следующие шифры соединений поддерживают форвардную секретность (FS) и работают с ATS:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
Обновление: выясняется, что openssl предоставляет только минимальную версию протокола. Протокол: TLSv1 ссылки
Ответ 5
После двух дней попыток и сбоев, что сработало для меня, это код womble
с одним изменением, в соответствии с этим post нам следует прекратить использовать под-ключи, связанные с словарем NSExceptionDomains такого рода Конвенции
NSTemporaryExceptionMinimumTLSVersion
И использовать на новой Конвенции
NSExceptionMinimumTLSVersion
вместо.
документация по яблоку
мой код
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>YOUR_HOST.COM</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Ответ 6
Другим полезным инструментом является nmap (brew install nmap)
nmap --script ssl-enum-ciphers -p 443 google.com
Выдает вывод
Starting Nmap 7.12 ( https://nmap.org ) at 2016-08-11 17:25 IDT
Nmap scan report for google.com (172.217.23.46)
Host is up (0.061s latency).
Other addresses for google.com (not scanned): 2a00:1450:4009:80a::200e
PORT STATE SERVICE
443/tcp open https
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
| TLSv1.1:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
| TLSv1.2:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
| compressors:
| NULL
| cipher preference: client
|_ least strength: C
Nmap done: 1 IP address (1 host up) scanned in 5.48 seconds
Ответ 7
Эта ошибка появлялась в журналах иногда, когда я использовал ошибку с ошибкой /crashy версии IOS от Кордовы. Он ушел, когда я обновил или понизил уровень кордовы iOS.
Сервер, к которому я подключался, использовал протокол TLSv1.2 SSL, поэтому я знал, что это не проблема.
Ответ 8
В файле проекта .plist
добавьте это разрешение:
<key>NSAppTransportSecurity</key>
<dict>
<!--Connect to anything (this is probably BAD)-->
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Ответ 9
Синтаксис конфигурации Info.plist
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow insecure HTTP requests-->
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
Ответ 10
Обновленный ответ (после WWDC 2016):
Приложения iOS потребуют безопасных HTTPS-соединений к концу 2016. Попытка отключить ATS может привести к тому, что ваше приложение будет отклонено в будущем.
App Transport Security или ATS - это функция, которую Apple представила в iOS 9. Когда включена служба ATS, она заставляет приложение подключаться к веб-службам через соединение HTTPS, а не небезопасный HTTP.
Однако разработчики все еще могут отключить ATS и разрешить своим приложениям отправлять данные по HTTP-соединению, как указано в приведенных выше ответах. В конце 2016 года Apple сделает ATS обязательным для всех разработчиков, которые надеются представить свои приложения в App Store. ссылка
Ответ 11
Устройство, на которое я тестировал, установило неправильное время. Поэтому, когда я попытался получить доступ к странице с сертификатом, который скоро закончится, он откажет в доступе, потому что устройство, хотя срок действия сертификата истек. Чтобы исправить, установите правильное время на устройстве!
Ответ 12
info.plist, как показано ниже, или просто скопируйте и проделайте мою работу до iOS 9.2
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
Ответ 13
Почему это слишком сложно -
Просто установите iOS Development Target - 8.0
И Cmd + Shift + K