調試信息:
測試環境是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