[ios] CFNetwork SSLHandshake failed iOS 9

has anyone with the iOS 9 beta 1 had this issue?

I use standard NSURLConnection to connect to a webservice and as soon as a call is made to the webservice i get the below error. This is currently working in iOS 8.3

Possible beta bug? any ideas or thoughts would be great ! I know its very early in iOS 9 development

Here is the full error:

CFNetwork SSLHandshake failed (-9824) NSURLSession/NSURLConnection HTTP load failed (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];

This question is related to ios ssl nsurlconnection ios9

The answer is


The device I tested at had wrong time set. So when I tried accessing a page with a certificate that would run out soon it would deny access because the device though the certificate had expired. To fix, set proper time on the device!


The syntax for the Info.plist configuration

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


This error was showing up in the logs sometimes when I was using a buggy/crashy Cordova iOS version. It went away when I upgraded or downgraded cordova iOS.

The server I was connecting to was using TLSv1.2 SSL so I knew that was not the problem.


In your project .plist file in add this permission :

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

In iOS 10+, the TLS string MUST be of the form "TLSv1.0". It can't just be "1.0". (Sigh)


The following combination of the other Answers works.

Let's say you are trying to connect to a host (YOUR_HOST.COM) that only has TLS 1.0.

Add these to your app's 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>

Another useful tool is nmap (brew install nmap)

nmap --script ssl-enum-ciphers -p 443 google.com

Gives output

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

For more info Configuring App Transport Security Exceptions in iOS 9 and OSX 10.11

Curiously, you’ll notice that the connection attempts to change the http protocol to https to protect against mistakes in your code where you may have accidentally misconfigured the URL. In some cases, this might actually work, but it’s also confusing.

This Shipping an App With App Transport Security covers some good debugging tips

ATS Failure

Most ATS failures will present as CFErrors with a code in the -9800 series. These are defined in the Security/SecureTransport.h header

2015-08-23 06:34:42.700 SelfSignedServerATSTest[3792:683731] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

CFNETWORK_DIAGNOSTICS

Set the environment variable CFNETWORK_DIAGNOSTICS to 1 in order to get more information on the console about the failure

nscurl

The tool will run through several different combinations of ATS exceptions, trying a secure connection to the given host under each ATS configuration and reporting the result.

nscurl --ats-diagnostics https://example.com

Updated Answer (post-WWDC 2016):

iOS apps will require secure HTTPS connections by the end of 2016. Trying turn ATS off may get your app rejected in the future.

App Transport Security, or ATS, is a feature that Apple introduced in iOS 9. When ATS is enabled, it forces an app to connect to web services over an HTTPS connection rather than non secure HTTP.

However, developers can still switch ATS off and allow their apps to send data over an HTTP connection as mentioned in above answers. At the end of 2016, Apple will make ATS mandatory for all developers who hope to submit their apps to the App Store. link


After two days of attempts and failures, what worked for me is this code of womble

with One change, according to this post we should stop using sub-keys associated with the NSExceptionDomains dictionary of that kind of Convention

  NSTemporaryExceptionMinimumTLSVersion

And use at the new Convention

  NSExceptionMinimumTLSVersion

instead.

apple documentation

my code

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

If your backend uses a secure connection ant you get using NSURLSession

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

you need to check your server configuration especially to get ATS version and SSL certificate Info:

Instead of just Allowing Insecure Connection by setting NSExceptionAllowsInsecureHTTPLoads = YES , instead you need to Allow Lowered Security in case your server do not meet the min requirement (v1.2) for ATS (or better to fix server side).

Allowing Lowered Security to a Single Server

<key>NSExceptionDomains</key>
<dict>
    <key>api.yourDomaine.com</key>
    <dict>
        <key>NSExceptionMinimumTLSVersion</key>
        <string>TLSv1.0</string>
        <key>NSExceptionRequiresForwardSecrecy</key>
        <false/>
    </dict>
</dict>

use openssl client to investigate certificate and get your server configuration using openssl client :

openssl s_client  -connect api.yourDomaine.com:port //(you may need to specify port or  to try with https://... or www.)

..find at the end

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) require Transport Layer Security (TLS) protocol version 1.2.

Requirements for Connecting Using ATS:

The requirements for a web service connection to use App Transport Security (ATS) involve the server, connection ciphers, and certificates, as follows:

Certificates must be signed with one of the following types of keys:

  • Secure Hash Algorithm 2 (SHA-2) key with a digest length of at least 256 (that is, SHA-256 or greater)

  • Elliptic-Curve Cryptography (ECC) key with a size of at least 256 bits

  • Rivest-Shamir-Adleman (RSA) key with a length of at least 2048 bits An invalid certificate results in a hard failure and no connection.

The following connection ciphers support forward secrecy (FS) and work with 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

Update: it turns out that openssl only provide the minimal protocol version Protocol : TLSv1 links


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to ssl

Requests (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.") Error in PyCharm requesting website A fatal error occurred while creating a TLS client credential. The internal error state is 10013 curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number How to install OpenSSL in windows 10? ssl.SSLError: tlsv1 alert protocol version Invalid self signed SSL cert - "Subject Alternative Name Missing" "SSL certificate verify failed" using pip to install packages ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749) Powershell Invoke-WebRequest Fails with SSL/TLS Secure Channel "ssl module in Python is not available" when installing package with pip3

Examples related to nsurlconnection

The resource could not be loaded because the App Transport Security policy requires the use of a secure connection CFNetwork SSLHandshake failed iOS 9 NSURLConnection Using iOS Swift Sending an HTTP POST request on iOS Easiest way to detect Internet connection on iOS?

Examples related to ios9

What does the shrink-to-fit viewport meta attribute do? Change status bar text color to light in iOS 9 with Objective-C The resource could not be loaded because the App Transport Security policy requires the use of a secure connection Transport security has blocked a cleartext HTTP How can I add NSAppTransportSecurity to my info.plist file? Delay/Wait in a test case of Xcode UI testing iOS 9 not opening Instagram app with URL SCHEME New warnings in iOS 9: "all bitcode will be dropped" NSURLSession/NSURLConnection HTTP load failed on iOS 9 How do I load an HTTP URL with App Transport Security enabled in iOS 9?