At WWDC 2015, Apple announced “App Transport Security” for iOS 9 and OSX 10.11 El Capitan. The “What’s New in iOS” guide for iOS 9 explains:
“App Transport Security (ATS) lets an app add a declaration to its Info.plist file that specifies the domains with which it needs secure communication. ATS prevents accidental disclosure, provides secure default behavior, and is easy to adopt. You should adopt ATS as soon as possible, regardless of whether you’re creating a new app or updating an existing one.
If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible.”
Which means, if your App attempts to connect to any HTTP server (in this example, https://gdccas/v1/login) that doesn’t support the latest SSL technology (TLSv1.2), your connections will fail with an error like this:
During development there are three ways to let your App run well with iOS SDK 9.
1.If your current web server is using HTTP instead of HTTPS
Open your App project with Xcode 7, locate the info.plist, right click and open as “Source Code”, then add below code inside <dict>
These codes will allow HTTP (without SSL) for your target server communicating with the App. Other options can be found in Apple Developer.
2.If your current web server is using HTTPS but without the willing to support ATS
You may need to contact the web server’s owner to upgrade the SSL, but if it’s hard to contact the right people, or there is no willing to upgrade the SSL, then the only way left is to disable ATS. Open your App project with Xcode 7, locate the info.plist, right click and open as “Source Code”, then add below code inside <dict>
Warning: this is not a secure method, you do it at your own risk!
3.If your current web server is using HTTPS with the willing to support ATS
In that case, there is nothing to do in Xcode, but have to configure the web server. You may need to contact the web server’s owner to configure the SSL. The requirements to let web server support ATS are:
1)TLS requires at least version 1.2.
2)Connection ciphers are limited to those that provide forward secrecy (see below for the list of ciphers.)
3)The service requires a certificate using at least a SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256bit or greater Elliptic-Curve (ECC) key.
4)Invalid certificates result in a hard failure and no connection.
The accepted ciphers are:
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
Take Apache HTTP Server as the example, to configure the SSL, first of all, please check and update software if necessary:
The recommend and necessary version are:
- OpenSSL 1.0.1c+
- Apache 2.4.x+
- nginx 1.0.6+ and 1.1.0+ (optional, if use this)
Secondly, create a 2048 bit key pair by OpenSSL:
openssl genrsa -out my.key 2048
Thirdly, create the Create Certificate Request (CSR) with SHA256:
openssl req -new -key my.key -out my.csr -new -sha256
Fourthly, apply for a wildcard certificate
Apply for a third party signed certificate with the created CSR file. You may need to find a third party online for the application, fees might be taken for that as well.
IMPORTANT, ATS won’t work with a self-signed certification.
After that, it’s time to configure the Apache Configuration file, which is usually called httpd.conf. Four steps should be done with that file:
Step 1: disable SSLv2 and SSLv3, change below line into the conf file:
SSLProtocol All -SSLv2 -SSLv3
Step 2: disable ssl compression, change below line into the conf file:
SSLCompression off
Step 3: Change the chipper suite, change below line into the conf file:
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
Step 4: Restart the Apache server:
Please fine related command online, as different OS (Linux, Unix, Ubuntu, CentOS) have different commands to restart a service.
Finally, you may need to check the SSL with:
openssl s_client -connect yourdomain:443
After all those steps done, check the connection again from your App, the ATS shall be work fine if you follow the steps above.
Hi Mark,
My web server is using HTTPS, and it is configured to support TLS 1.2 only, however the Certificate is not supporting forward secrecy. Can my iOS client with ATS bypassed still connect to the web server?
When the client connect to the server for authorization process, the web server generated a ticket and sent it back to the iOS client, however, when I use the same ticket to make further call to the back end server, the ticket can not be recognized by the server. When I compare the iOS client ticket with the Windows API Tester ticket (this is working), the iOS client ticket is much shorter.
Sorry, I’m a newbie.