IOS-关于App Transport Security相关说明及适配

转载自[http://blog.csdn.net/maxdong24/article/details/53610127]

iOS9中新增App Transport Security(简称ATS)特性, 主要使到原来请求的时候用到的HTTP,都转向TLS1.2协议进行传输。这也意味着所有的HTTP协议都强制使用了HTTPS协议进行传输。原文如下:

App Transport Security

App Transport Security (ATS) enforces best practices in the 
secure connections between an app and its back end. ATS 
prevents accidental disclosure, provides secure default behavior, 
and is easy to adopt; it is also on by default in iOS 9 and OS X 
v10.11. 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. In addition, your communication through 
higher-level APIs needs to be encrypted using TLS version 1.2 with 
forward secrecy. If you try to make a connection that doesn’t 
follow this requirement, an error is thrown. If your app needs to 
make a request to an insecure domain, you have to specify this 
domain in your app’s Info.plist file.

如果我们在iOS9下直接进行HTTP请求是会收到如下错误提示:

App Transport Security has blocked a cleartext HTTP ([http://] resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.

新特性要求App内访问的网络必须使用HTTPS协议,具体内容大家可以自行度娘,

我们这里只是说明一下如何关闭该特性,让其可以访问http开头的网址.

关闭很简单,打开项目中的info.plist文件,在其中添加一个字典类型的项目App Transport Security Settings,然后在其中添加一个key:Allow Arbitrary Loads,其值为YES.如下所示:

NSAppTransportSecurity

    NSAllowsArbitraryLoads
    

这段配置中的NSAppTransportSecurity是ATS配置的根节点,配置了节点表示告诉系统要走自定义的ATS设置。而NSAllowsAritraryLoads节点则是控制是否禁用ATS特性,设置YES就是禁用ATS功能。

如果想要设置某个域名禁用ATS可以在plist文件中加以下代码:

NSAppTransportSecurity

    NSExceptionDomains
    
        your domain
        
            NSIncludesSubdomains
            
            NSExceptionRequiresForwardSecrecy
            
            NSExceptionAllowsInsecureHTTPLoads
            
        
    

NSIncludesSubdomains设置为YES表示百度的子级域名都使用相同设置。

NSExceptionRequiresForwardSecrecy为NO由于网址不支持ForwardSecrecy,因此屏蔽掉改功能。

NSExceptionAllowInsecureHTTPLoads设置为YES,则表示允许访问没有证书或者是自签名、过期、主机名不匹配的证书引发的错误的域名(这里检查过百度的证书貌似没有什么问题,但是还是需要设置此项才允许访问)。

ATS是在iOS 9.0 和 OS X v10.11版本中增加的特性,使用iOS 9.0或者OS X v10.11的SDK版本(或更新的SDK)进行编译应用时会默认启动ATS。则需要对ATS进行配置。如果使用iOS 9.0或者OS X v10.11之前的SDK版本编译的应用默认是禁止ATS的,因此不会影响应用的网络连接方面的功能(即使在iOS 9.0的机子上跑也是不影响的)。
其实ATS并不单单针对HTTP进行了限制,对HTTPS也有一定的要求,以百度的地址为例(注:举该栗子的时候百度是还没符合ATS的要求的,现在百度已经支持ATS),如果在App中请求https://www.baidu.com的话,是会收到如下的错误信息:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

查阅了一下官方资料:(https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33),发现HTTPS的请求需要满足下面的要求:

Requirements for Connecting Using ATS

With ATS fully enabled, your app’s HTTP connections must use HTTPS and must satisfy the following security requirements:

The server certificate must meet at least one of the following trust requirements: 
Issued by a certificate authority (CA) whose root certificate is incorporated into the operating system 
Issued by a trusted root CA and installed by the user or a system administrator 
The negotiated Transport Layer Security version must be TLS 1.2 
The negotiated TLS connection cipher suite must support forward secrecy (FS) and be one of the following:

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

The leaf server certificate must be signed with one of the following types of keys: 
Rivest-Shamir-Adleman (RSA) key with a length of at least 2048 bits 
Elliptic-Curve Cryptography (ECC) key with a size of at least 256 bits 
In addition, the leaf server certificate hashing algorithm must be Secure Hash Algorithm 2 (SHA-2) with a digest length of at least 256 (that is, SHA-256 or greater).

根据原文描述,首先颁发给服务器证书的证书机构(CA)的根证书必须是内置于操作系统(哪些根证书被信任可以查看https://support.apple.com/zh-cn/HT205205,或者在你的机子的设置-通用-关于本机最下面的“进一步了解被信任的证书”中查看)或者受用户或者系统管理员信任并安装到操作系统上的。而且必须要基于TLS 1.2版本协议。再来就是连接的加密方式要提供Forward Secrecy(FS正向保密,感兴趣的筒子可以看看这个https://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy.html),文档中罗列出了支持的加密算法(上面的原文中有说明,我把它独立抽出来放到下面表格中查看)。最后就是证书至少要使用一个SHA256的指纹与任一个2048位或者更高位的RSA密钥,或者是256位或者更高位的ECC密钥。如果不符合其中一项,请求将被中断并返回nil。
下面举例说明: 用浏览器打开一个链接,然后点击左侧的小锁头,点击详细信息,查看证书和算法等信息。
点击证书信息,查看颁发给它证书的CA的根证书,如图:

IOS-关于App Transport Security相关说明及适配_第1张图片
这里写图片描述

IOS-关于App Transport Security相关说明及适配_第2张图片
这里写图片描述

Secure Connection The connection to this site is encrypted and authenticated using a strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with P-256), and a strong cipher (AES_128_GCM).

可以看到【带 RSA 加密的 SHA-256 ( 1.2.840.113549.1.1.11 )】使用了TLS 1.2版本协议,符合上面所说的TLS版本的约定。

最后,说到如何诊断一个URL是否支持ATS,这里给大家介绍一些nscurl这个命令行工具,这个工具是OS X v10.11上新增的,主要用于诊断ATS带来的连接问题,利用它可以在命令行中直接检测一个URL地址是否支持ATS。其用法如下:

/usr/bin/nscurl –ats-diagnostics [–verbose] URL

URL - 表示用来诊断的网址
verbose - 该选项将会为每次的连接包含更多信息,包括使用到Info.plist中的哪些key和对应的值也会列出来。

输出的结果都是Pass的了,那证明你查看的链接是支持ATS的。

例,检测阿里云官网www.aliyun.com

 /usr/bin/nscurl --ats-diagnostics --verbose https://www.aliyun.com

Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://www.aliyun.com.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================

Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---

================================================================================

Allowing Arbitrary Loads

---
Allow All Loads
ATS Dictionary:
{
    NSAllowsArbitraryLoads = true;
}
Result : PASS
---

================================================================================

Configuring TLS exceptions for www.aliyun.com

---
TLSv1.2
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
        };
    };
}
Result : PASS
---

---
TLSv1.1
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
        };
    };
}
Result : PASS
---

---
TLSv1.0
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions for www.aliyun.com

---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring PFS exceptions and allowing insecure HTTP for www.aliyun.com

---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled for www.aliyun.com

---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for www.aliyun.com

---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.2";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.1";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
    NSExceptionDomains =     {
        "www.aliyun.com" =         {
            NSExceptionAllowsInsecureHTTPLoads = true;
            NSExceptionMinimumTLSVersion = "TLSv1.0";
            NSExceptionRequiresForwardSecrecy = false;
        };
    };
}
Result : PASS
---

================================================================================
如果出现FAIL情况,请看以下两点: 
1.签名算法–》带 RSA 加密的 SHA-256 ( 1.2.840.113549.1.1.11 ) 
2.Secure Connection 
The connection to this site is encrypted and authenticated using a strong protocol (TLS 1.2), a strong key exchange (ECDHE_RSA with P-256), and a strong cipher (AES_128_GCM).

看以上两点是否匹配。

你可能感兴趣的:(IOS-关于App Transport Security相关说明及适配)