是否有人使用iOS 9 beta 1遇到此问题?
我使用标准的NSURLConnection连接到一个web服务,一旦调用到web服务,我得到下面的错误。这是目前在iOS 8.3
可能的beta bug?任何想法或想法都会很棒!我知道这是iOS 9开发的早期阶段
下面是完整的错误:
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];
iOS 9和OSX 10.11要求所有主机TLSv1.2 SSL,除非你在应用的Info中指定例外域。plist文件。
Info的语法。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>
如果您的应用程序(例如第三方web浏览器)需要连接到任意主机,您可以这样配置它:
<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"。(叹气)
下列答案的组合是有效的。
让我们假设你正在尝试连接到一个只有TLS 1.0的主机(YOUR_HOST.COM)。
将这些添加到应用程序的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>
更多信息在iOS 9和OSX 10.11中配置应用传输安全异常
奇怪的是,您会注意到连接试图更改HTTP协议转换为HTTPS以防止代码中的错误您可能不小心配置错了URL。在某些情况下,这可能实际工作,但也令人困惑。
This Shipping an App With App Transport Security涵盖了一些很好的调试技巧
at失败
大多数ATS故障将显示为代码为-9800的cferror系列。这些在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
如果你的后端使用安全连接,你可以使用NSURLSession
CFNetwork SSLHandshake failed (-9801)
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)
你需要检查你的服务器配置,特别是获得ATS版本和SSL证书信息:
而不是仅仅允许不安全连接通过设置NSExceptionAllowsInsecureHTTPLoads = YES
,相反,您需要允许降低安全性,以防您的服务器不满足ATS的最低要求(v1.2)(或更好地修复服务器端)。
允许降低单个服务器的安全性
<key>NSExceptionDomains</key>
<dict>
<key>api.yourDomaine.com</key>
<dict>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
使用openssl client检查证书并使用openssl client获取服务器配置:
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)需要传输层安全(TLS)协议版本1.2。
ATS接线要求:
使用ATS (App Transport Security)的web服务连接要求包括服务器、连接密码和证书,具体如下:
证书必须使用以下类型的密钥之一进行签名:
安全散列算法2 (SHA-2)密钥,摘要长度至少为256(即SHA-256或更大)
长度至少为256位的椭圆曲线加密(ECC)密钥
RSA (Rivest-Shamir-Adleman)密钥,长度至少2048位无效的证书将导致硬故障和无连接。
下列连接密码支持前向保密(FS)和工作ATS:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHATLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHATLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
更新:原来openssl只提供最小的协议版本协议:TLSv1链接
经过两天的尝试和失败,我成功了
一个变化,根据这篇文章,我们应该停止使用与NSExceptionDomains字典相关联的子键,这种约定 NSTemporaryExceptionMinimumTLSVersion
并在新的约定
中使用 NSExceptionMinimumTLSVersion
。
苹果文档我的代码<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
当我使用一个有bug/崩溃的Cordova iOS版本时,这个错误有时会出现在日志中。当我升级或降级cordova iOS时,它就消失了。
我正在连接的服务器使用TLSv1.2 SSL,所以我知道这不是问题。
在您的项目.plist
文件中添加此权限:
<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>
更新答案(2016年post-WWDC):
到年底,iOS应用将需要安全的HTTPS连接2016. 尝试关闭ATS可能会导致你的应用在将来被拒绝。
App Transport Security,简称ATS,是苹果在iOS 9中引入的一项功能。当启用ATS时,它会强制应用程序通过HTTPS连接而不是非安全的HTTP连接到web服务。
但是,开发人员仍然可以关闭ATS,并允许他们的应用程序通过HTTP连接发送数据,如上面的答案所述。2016年底,苹果将强制要求所有希望向App Store提交应用的开发者使用ATS 。link我测试的设备时间设置错误。因此,当我试图访问一个带有即将过期证书的页面时,它会拒绝访问,因为设备认为证书已经过期。要修复,请在设备上设置适当的时间!