NSURLSession "HTTP 加载失败 kCFStreamErrorDomainSSL, -9813 ; 自签名证书
Posted
技术标签:
【中文标题】NSURLSession "HTTP 加载失败 kCFStreamErrorDomainSSL, -9813 ; 自签名证书【英文标题】:NSURLSession "HTTP load failed kCFStreamErrorDomainSSL, -9813 ; Self signing certificate 【发布时间】:2015-08-27 18:32:29 【问题描述】:我正在尝试将我的 ios 应用程序连接到当前在我网络中的本地主机上运行的 HTTPS Rails 应用程序。我可以使用 https://myIP:3000/display
从浏览器访问该站点,也可以使用 curl 请求在命令行中访问该站点。我正在尝试使用以下方式从我的应用程序中访问它:
class FirstViewController: UIViewController
override func viewDidLoad()
super.viewDidLoad()
//let url = NSURL(string: "https://another/Sinatra/website/feed")
let url = NSURL(string: "https://myIP:3000/display")
let request = NSURLRequest(URL: url!)
let task = NSURLSession.sharedSession().dataTaskWithURL(url!)
task!.resume()
当我尝试访问 sinatra 网站时,我没有遇到任何问题,甚至可以使用正确的命令将 JSON 打印到控制台。但是,当我将 url 设置为我的 Rails 网站时,我收到以下错误。
NSURLSession/NSURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9813)
此外,我可以看出我的 localhost Rails 应用程序(在另一台机器上)没有从 iOS 应用程序 ping,而是从浏览器和 curl 命令 ping。
任何想法如何解决这个问题?
【问题讨论】:
将您的代码放入viewWillDisplay
或viewDidDisplay
。 viewDidLoad
对大多数事情来说都太早了。
iOS 和 Swift 哪个版本?将该信息添加到问题中。
CFNetwork SSLHandshake failed iOS 9 Beta 1 的可能重复项
NSURLSession/NSURLConnection HTTP load failed的可能重复
也发生在 Objective C 中(不仅在 swift 上)
【参考方案1】:
如果我理解得很好,Apple 现在希望开发人员使用 HTTPS 和 TLS 1.2 进行网络调用。
临时的,你可以在你的“Info.plist”文件中添加这个:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
看看这个链接,它也可能对你有帮助:http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/
--
更新:在一些 cmets 之后,上述解决方案不再有效。这是一个更新的解决方案。
-
转到您的
Info.plist
文件。
添加一行 Type Dictionary
和 Key App Transport Security Settings
。
在此字典中,添加一行 Type Boolean
、Key Allow Arbitrary Loads
和 Value YES
-
否则你可以设置Domain Exceptions
。这是怎么做的:
-
转到您的
Info.plist
文件。
添加一行 Type Dictionary
和 Key App Transport Security Settings
。
添加一行 Type Dictionary
和 Key Exception Domains
。
添加一行 Type Dictionary
和 Key The domain
。
将两行 Type Boolean
和 Key NSExceptionAllowsInsecureHTTPLoads
& NSIncludesSubdomains
与 Value 添加到 YES
。
链接
https://forums.developer.apple.com/message/5857#5857
2015 WWDC Session 711
iOS 9 HTTP Connection Error - ***
【讨论】:
不只是 https,它必须是 TLS 1.2。 这在 iOS 模拟器中似乎不起作用。你在模拟器中工作了吗? 不再适用于 iOS 10。修复方法是什么? (感谢 Apple 让我们知道他们会破坏我们的应用程序 - 不是 :-) 有趣的是,我在使用 TLS 1.2 连接时遇到了类似的错误。这是与具有真实 SSL 证书的生产服务器通信。 Allow Arbitrary Loads 使这项工作。【参考方案2】:这是一个信任问题。使用自签名证书,SSL 的身份验证组件不起作用。仍然可以建立安全连接,以便没有人窃听,但应用程序无法确定谁在线路的另一端。
我有类似的设置,并通过将我的自签名根 CA 添加到 iPad 受信任证书来解决此问题。这个根 CA 用于签署我所有的其他开发证书。然后我只需在将使用 SSL 的任何地方添加这个单一的根证书。如果您只有一个直接使用的自签名证书,您可以添加它。
为了在设备(或模拟器)上获取证书,我将文件放在我的网络服务器上。然后只需通过普通 HTTP 在 Safari 中打开它。设置应用程序应该会打开并询问您是否要信任证书。
当然,这是假设这仅用于开发,并且您的生产系统具有由知名机构签署的证书(即包含在操作系统的根证书机构数据库中的证书)。因为要求最终用户安装您的自签名证书是行不通的。
【讨论】:
是的,但是您将哪个文件放在服务器上?我把我的 .cert 和 Safari 只是作为文本文件打开。 我将我的自签名根 CA 放在服务器上并在 Safari 中打开它。我使用了扩展名.crt
我的服务器正在使用 真实 证书(非自签名),但我仍然遇到此问题...【参考方案3】:
这是唯一对我有用的解决方案...在 AppDelegate.m 文件的末尾,插入代码:
@implementation NSURLRequest(DataController)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host
return YES;
@end
感谢 jc ivancevich 的文章http://ivancevich.me/articles/ignoring-invalid-ssl-certificates-on-cordova-android-ios/
【讨论】:
【参考方案4】:(编辑 - 我将其误读为 9814,证书已过期。我不确定如何解决这个问题,但希望我的回答有助于指明正确的方向。)
看起来像是与通常的“允许任意负载”问题不同的证书问题。
摘自:Apple Documentation - Appendix A: Common Server Trust Evaluation Errors
NSOSStatusErrorDomain errSSLNoRootCert -9813
【讨论】:
【参考方案5】:尝试改变会话变量,这个改变对我有帮助
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
【讨论】:
【参考方案6】:修改 info.plist 也对我有用。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
【讨论】:
【参考方案7】:NSURLSession/NSURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9813)
在您的 plist 文件中添加一个新行。
【讨论】:
这只是对现有答案的重复。以上是关于NSURLSession "HTTP 加载失败 kCFStreamErrorDomainSSL, -9813 ; 自签名证书的主要内容,如果未能解决你的问题,请参考以下文章
使用 NSURLSession 处理 HTTP 错误的最佳实践?