在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