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


Answers

** ВАЖНОЕ ЗАМЕЧАНИЕ ДЛЯ 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>
Question

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

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

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

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

Ошибка CFNetwork SSLHandshake (-9824) Ошибка загрузки 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];



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




В файле проекта .plist добавьте это разрешение:

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



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

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

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

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




Другим полезным инструментом является 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



Если ваш бэкэнд использует безопасное соединение, и вы получаете использование 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) требуется Transport Layer Security (TLS) версия 1.2.

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

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

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

  • Secure Hash Algorithm 2 (SHA-2) с длиной дайджеста не менее 256 (то есть SHA-256 или выше)
  • Эллиптическая кривая криптографии (ECC) с размером не менее 256 бит

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

Следующие шифры соединений поддерживают форвардную секретность (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- ссылки.