在HTTPS环境下使用NSURLSession,证书验证无法通过

调试信息

测试环境是SSL3.0/TLS1.0,证书是通过Verisign颁发的

错误信息是:9846, An ssl error has occurred and a secure connection to the server cannot be made

实现了“NSURLSession:didReceiveChallenge:completionHandler”, 并使用“completionHandler(NSURLSessionAuthChallengePerformDefaultHandling,

>nil)”

回答无效,收到三次challenge后Request失败

可以使用独立的代码重现这个问题,所以可以确定与APP本身逻辑无关

在iPad上装了服务器证书,但是问题依然存在

ATS已经关闭

换回NSURLConnection验证可以通过: 在“connection:canAuthenticateAgainstProtectionSpace:”方法中返回NO,可以直接忽略Server Trust Challenge

解决方法

为什么收到多次的challenge,最终还是失败:需要连接的服务器并不支持TLS1.2,而iOS默认支持的版本是TLS1.2,这样,iOS在失败后会尝试着继续与服务器连接,这里的不同点是,NSURLConnection会尝试低版本的TLS,但是NSURLSession却会继续尝试TLS1.2,这就导致了连接失败

最简单也是推荐的解决方法是升级服务器,支持TLS1.2

如果还是希望支持TLS1.0:

将:NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];

修改成:

NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];

config.TLSMaximumSupportedProtocol = kTLSProtocol1;

NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

这里将最高版本设置成1.0,也就是意味着NSURLSession将只会尝试连接TLS1.0。

其实这里有个问题,我们尝试过将“TLSMinimumSupportedProtocol” 设置成TLS1.0,但是事实上iOS并不会去尝试连接低版本的TLS

注:从博客园迁移 20151216

你可能感兴趣的:(在HTTPS环境下使用NSURLSession,证书验证无法通过)