CFNetwork SSLHandshake失败的iOS 9


207

拥有iOS 9 beta 1的人有这个问题吗?

我使用标准NSURLConnection连接到Web服务,并且一旦调用该Web服务,我就会收到以下错误。目前在iOS 8.3中有效

可能的Beta错误?任何想法或想法都会很棒!我知道它在iOS 9开发的早期

这是完整的错误:

CFNetwork SSLHandshake失败(-9824)NSURLSession / NSURLConnection HTTP加载失败(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];

Answers:


310

除非您在应用程序的Info.plist文件中指定例外域,否则iOS 9和OSX 10.11要求您计划向其请求数据的所有主机使用TLSv1.2 SSL。

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(如果尚未这样做)。这应被视为临时解决方法。

到目前为止,预发行版文档没有以任何特定方式提及任何这些配置选项。完成后,我将更新答案以链接到相关文档。


1
应用程序传输安全性(ATS)使应用程序可以在其Info.plist文件中添加一个声明,该声明指定需要与之进行安全通信的域。ATS可以防止意外泄露,提供安全的默认行为,并且易于采用。无论您是创建新应用还是更新现有应用,都应尽快采用ATS。如果要开发新的应用程序,则应专门使用HTTPS。如果您已有应用程序,则应立即使用HTTPS,并制定一个计划,以尽快迁移其余应用程序。
user3099837 2015年

2
@StevenPeterson嗨,史蒂夫,我似乎无法使例外域示例正常工作,您是否有任何偶然的想法,我只是复制并粘贴到.plist中,将TLSv1.1更改为TLSv1.0,并将该域更改为没有https的域: //等
user3099837 2015年

27
很抱歉,长时间的聊天,但是我发现我需要禁用<key> NSTemporaryExceptionRequiresForwardSecrecy </ key> <false />
user3099837 2015年

2
@RashmiRanjanmallick NSTemporaryExceptionMinimumTLSVersion用于告诉ATS您正在使用非1.2服务器。例如,如果您尝试连接到使用TLS 1.0的主机,请使用此选项。您还必须使用NSTemporaryExceptionRequiresForwardSecrecy设置为false,如上面指出的user3099837所示。
2015年

2
ste.vn/2015/06/10/…-这是答案的博客。
肖恩·德夫

66

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

9
似乎添加NSTemporaryExceptionRequiresForwardSecrecy为我成功了,谢谢!
Josh Valdivieso 2015年

2
这个版本在iOS9.1上不适合我-我需要在其他答案之一中使用TLSVersion字符串格式<key> NSTemporaryExceptionMinimumTLSVersion </ key> <string> TLSv1.1 </ string>
300baud

这可行,但是我的问题是:这是否意味着当这些参数打开且数据未加密时,我的应用程序不使用ssl?
theDC '16

33

有关更多信息,请在iOS 9和OSX 10.11中配置App Transport Security例外。

奇怪的是,您会注意到该连接尝试将http协议更改为https,以防止您的代码中可能不小心错误配置了URL的错误。在某些情况下,这可能确实有效,但也令人困惑。

航运的应用程序使用App交通运输安全介绍了一些很好的调试技巧

ATS失败

大多数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

1
仅说明nscurl仅在Mac OS X“ El Capitan”中可用
webo80

1
一个更调试尖端,以检查正在使用由服务器TLS连接密码:卷曲-v HTTPS:// <主机名>
安德烈Morujão

1
如果卷曲PASS所有步骤都正常,对什么可能导致问题的任何想法?
阿斯顿(Aston)2015年

@ onmyway133是否可以添加有关如何“将环境变量CFNETWORK_DIAGNOSTICS设置为1”的说明?
YakirNa '16

1
@YakirNa您可以在此处阅读有关如何执行此操作的信息nshipster.com/launch-arguments-and-environment-variables非常简单:)
onmyway133

2

如果您的后端使用安全的连接蚂蚁,则可以使用NSURLSession

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

您需要检查服务器配置,尤其是要获取ATS版本和SSL证书信息:

不只是 允许安全连接的设置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)需要传输层安全性(TLS)协议版本1.2。

使用ATS连接的要求:

Web服务连接使用App Transport Security(ATS)的要求涉及服务器,连接密码和证书,如下所示:

证书必须使用以下其中一种密钥进行签名:

  • 摘要长度至少为256(即SHA-256或更大)的安全哈希算法2(SHA-2)密钥

  • 椭圆曲线密码术(ECC)密钥,其大小至少为256位

  • 长度至少为2048位的Rivest-Shamir-Adleman(RSA)密钥无效的证书会导致硬故障并且无法连接。

以下连接密码支持前向保密(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仅提供最低协议版本Protocol:TLSv1 链接


问题仍然存在,是否有可能解释openssl信息以找出服务器是否满足要求。另外协议:TLSv1可能是makor版本,而不是1.x
Idali 2015年

我将其通用化,以防使用端口
Idali 2015年

答案留下的问题多于答案。似乎可能是opensl报告与Apple文档之间的映射问题。从openssl输出中无法确定是否支持TLS 1.2。答案还不允许确定是否支持完全向前保密。
zaph 2015年

2

经过两天的尝试和失败,对我有用的是这段womble代码

进行了一次更改,根据这篇文章,我们应该停止使用与此类Convention 的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>

1

另一个有用的工具是nmap(简装安装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

调试证书问题非常有用
Lopakhin 16'Aug

0

当我使用越野车/疯狂的Cordova iOS版本时,有时会在日志中显示此错误。当我升级或降级cordova iOS时,它消失了。

我连接到的服务器正在使用TLSv1.2 SSL,所以我知道这不是问题。


0

在您的项目 .plist文件中添加以下权限:

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

0

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>


0

更新的答案(WWDC后2016):

iOS应用到2016年底将需要安全的HTTPS连接。尝试关闭ATS可能会在将来使您的应用被拒绝。

App Transport Security或ATS是Apple在iOS 9中引入的功能。启用ATS时,它将强制应用程序通过HTTPS连接而非非安全HTTP连接到Web服务。

但是,开发人员仍然可以关闭ATS,并允许其应用通过HTTP连接发送数据,如上面的答案所述。在2016年底,Apple将对所有希望将其应用程序提交到App Store的开发人员强制使用ATS。链接


0

我在测试的设备设置了错误的时间。因此,当我尝试使用不久将用完的证书访问页面时,它将拒绝访问,因为尽管证书已过期,但设备仍然有效。要解决此问题,请在设备上设置适当的时间!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.