NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL



解决办法
在AppDelegate中添加


@implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
{
    return YES;
}
@end

这个问题会连 以下问题一起解决


nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9807]

在使用第三方登录以及分享等功能的时候要注意以下三个方法的实现,如果有某一个没有具体实现的话,也可能会有问题的
- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<NSString *,id> *)options
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url




http://www.cnblogs.com/fishbay/p/7216142.html



问题描述
在开发app时,遇到了在iOS 9中发送https请求报错的问题:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)
我们知道,在iOS 9以后,所有的网络请求默认使用https,如果你发送http请求,则会报如下错误,但是我们可以通过在info.plist中设置NSAppTransportSecurity - NSAllowsArbitraryLoads的值为YES来允许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.
info.plist



这样解决了http的请求问题,但是我发送是https请求,还是出现HTTP laod failed的问题,尽管使用上述方法也可以解决,但这不是根本的解决办法。

解决办法
经过分析,怀疑是TLS的问题,因为iOS 9默认需要TLS1.2版本来加密数据,如果服务端不支持TLS1.2,则URLSession:task:didCompleteWithError:会返回nil的error,但是后端开发同事说服务器支持TLS1.0、TLS1.1和TLS1.2,这好像又不是TLS的问题。于是不放心,用nscurl测试了一下测试服务器,果然不支持TLS1.2,问题找到。

# 加 --verbose 是为了显示详细的调试信息
/usr/bin/nscurl --ats-diagnostics --verbose https://testresource.chaoaicai.com
通过输出看出,服务器只支持TLS1.0,于是让后台开发的同事测试并修改后,再次测试,发现服务器支持TLS1.2了,并且https的网络请求也正常了。



ATS异常配置
其实,针对服务器不支持TLS1.2,而客户端发送https请求还有其它的解决方法,就是配置ATS,设置最低的TLS版本即可,如下info.plist所示:

<key>NSAppTransportSecurity</key>
  <dict>
  <key>NSExceptionDomains</key>
  <dict>
    <!--你的https域名-->
    <key>testresource.chaoaicai.com</key>
    <dict>
      <!--允许子域-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--TLS允许的最低版本号-->
      <key>NSExceptionMinimumTLSVersion</key>
      <string>TLSv1.0</string>
    </dict>
  </dict>
</dict>
其中,NSExceptionDomains的具体设置项介绍如下,可以更详细的了解ATS的异常配置

NSIncludesSubdomains:是否应用到子域名,默认是NO
NSExceptionAllowsInsecureHTTPLoads:是否允许http请求,YES(允许),默认是NO
NSExceptionMinimumTLSVersion:最低的TLS版本
NSExceptionRequiresForwardSecrecy:是否需要前置加密,NO(允许加密,但不支持PFS:perfect forward secrecy),默认是YES
NSRequiresCertificateTransparency:是否需要有效的签名证书,YES(需要),默认是NO
本文只是简单的介绍了一下如何配置ATS,及解决由于服务器不支持TLS1.2造成的https无法访问的问题,需要了解https、TLS的具体工作流程,请参考相关资料。

猜你喜欢

转载自maxer025.iteye.com/blog/2391610