CFNetwork SSLHandshake не удалось iOS 9

у кого-нибудь с iOS 9 beta 1 была эта проблема?

Я использую стандартный NSURLConnection для подключения к веб-сервису, и как только вызов сделан к веб-сервису, я получаю приведенную ниже ошибку. В настоящее время это работает в iOS 8.3

возможная ошибка бета-версии? любые идеи или мысли были бы великолепны ! Я знаю его очень рано в разработке iOS 9

вот полная ошибка:

CFNetwork SSLHandshake не удалось (-9824) Ошибка HTTP-загрузки NSURLSession / NSURLConnection (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];

13 ответов


iOS 9 и OSX 10.11 требуют TLSv1.2 SSL для всех хостов, которые вы планируете запросить данные, если вы не укажете Домены исключений в информации вашего приложения.plist файл.

синтаксис для информации.конфигурация 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, если они еще этого не делают. Это следует рассматривать как временное решение.

На сегодняшний день в предварительной документации не упоминается ни один из этих параметров конфигурации каким-либо конкретным образом. Как только это произойдет, я обновлю ответ, чтобы связать его с соответствующей документацией.


в iOS 10 + строка TLS должна иметь форму " TLSv1.0". Это не может быть просто "1.0". (Вздох)


работает следующая комбинация других ответов.

предположим, вы пытаетесь подключиться к хосту (YOUR_HOST.COM) , который имеет только TLS 1.0.

добавьте их к информации вашего приложения.файл 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>

дополнительная информация настройка исключений безопасности транспорта приложений в iOS 9 и OSX 10.11

Любопытно, что вы заметите, что соединение пытается изменить протокол http к https для защиты от ошибок в коде, где возможно, вы случайно неправильно настроили URL-адрес. В некоторых случаях это возможно, это и сработает, но это также сбивает с толку.

этой доставка приложения с App Transport Security крышки некоторые хорошие советы по отладке

сбой 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

если ваш сервер использует безопасное соединение ant вы получаете с помощью NSURLSession

CFNetwork SSLHandshake failed (-9801)
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)

вам нужно проверить конфигурацию сервера, особенно для получения версии ATS и SSL-сертификата:

вместо Позволяет Небезопасное Соединение установка 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)

App Transport Security (ATS) требуется протокол Transport Layer Security (TLS) версии 1.2.

требования к подключению с помощью ATS:

требования к a подключение к веб-службе для использования App Transport Security (ATS) включает сервер, шифры подключения и сертификаты следующим образом:

сертификаты должны быть подписаны одним из следующих типов ключей:

  • Безопасный хэш-алгоритм 2 (SHA-2) ключ с длиной дайджеста не менее 256 (то есть SHA-256 или больше)
  • ключ криптографии с эллиптической кривой (ECC) размером не менее 256 бит

  • ключ Rivest-Shamir-Adleman (RSA) длиной не менее 2048 бит недопустимый сертификат приводит к жесткому сбою и отсутствию соединения.

следующие шифры соединения поддерживают переднюю секретность (FS) и работу с ОВД:

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

Update: оказывается, openssl предоставляет только минимальный протокол версии протокола: TLSv1 ссылки


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

С одним изменением, согласно этому в должности мы должны прекратить использовать под-ключи, связанные с NSExceptionDomains словарь такого рода

  NSTemporaryExceptionMinimumTLSVersion

и использовать на новой конвенции

  NSExceptionMinimumTLSVersion
.

документация apple

код

<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>

еще один полезный инструмент-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

эта ошибка иногда появлялась в журналах, когда я использовал версию iOS buggy/crashy Cordova. Он ушел, когда я обновил или понизил Cordova iOS.

сервер, к которому я подключался, использовал TLSv1.2 SSL, поэтому я знал, что это не проблема.


в проекте В добавить это разрешение :

<key>NSAppTransportSecurity</key>
<dict>
    <!--Connect to anything (this is probably BAD)-->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

синтаксис для информации.конфигурационный файл 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>


обновленный ответ (после WWDC 2016):

приложения iOS потребуют безопасных HTTPS-соединений к концу 2016. Попытка отключить ATS может привести к отклонению вашего приложения в будущем.

App Transport Security, или ATS, это функция, которую Apple представила в iOS 9. Когда ATS включена, приложение подключается к веб-службам через HTTPS-соединение, а не через небезопасный HTTP.

однако разработчики все еще могут переключать ATS выключите и разрешите своим приложениям отправлять данные через HTTP-соединение, как указано в приведенных выше ответах. В конце 2016 года, Apple сделает ATS обязательно для всех разработчиков, которые надеются отправить свои приложения в App Store. ссылка


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


информация.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>

Почему это слишком сложно -

просто установите цель разработки iOS-8.0

enter image description here

enter image description here

и Cmd+Shift+K