IOS9获取错误“发生 SSL 错误,无法建立到服务器的安全连接”

自从我用 iOS9升级了我现有的项目,我就一直得到这个错误:

发生 SSL 错误,无法建立到服务器的安全连接。

200316 次浏览

对于 iOS9,苹果对 iOS9做出了一个激进的决定,作为 应用程序传输安全(ATS)的一部分,禁用了来自 iOS 应用程序的所有不安全的 HTTP 通信。

要简单地禁用 ATS,您可以按照以下步骤打开 Info.plist,并添加以下代码行:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

尽管允许任意加载(NSAllowsArbitraryLoads = true)是一个很好的解决方案,但是您不应该完全禁用 ATS,而应该启用希望允许的 HTTP 连接:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>yourserver.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>

IOS 9强制使用 HTTPS 的连接为 TLS 1.2,以避免最近的漏洞。在 iOS8中甚至支持未加密的 HTTP 连接,所以旧版本的 TLS 也不会造成任何问题。作为一种解决方案,您可以将下面的代码片段添加到 Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

* 参照 应用程序传输安全(ATS)

enter image description here

问题在于服务器端的 ssl 证书。要么是有什么东西在干扰,要么是证书与服务不匹配。例如,当你使用的服务在 www.mydomain.com 上运行时,一个网站有一个 ssl 认证 myservice.mydomain.com。那是另一台机器。

看起来 iOS9.0.2中断了对有效 HTTPS 端点的请求。我目前的怀疑是,它是需要 SHA-256证书或它失败与此错误。

要进行复制,请使用 safari 检查 UIWebView,并尝试导航到任意的 HTTPS 端点:

location.href = "https://d37gvrvc0wt4s1.cloudfront.net/js/v1.4/rollbar.min.js"
// [Error] Failed to load resource: An SSL error has occurred and a secure connection to the server cannot be made. (rollbar.min.js, line 0)

现在试着去谷歌一下(因为他们当然有 SHA-256证书) :

location.href = "https://google.com"
// no problemo

为传输安全性添加一个异常(如上面@st éphane-bruckert 的回答所述)可以解决这个问题。我还假设完全禁用 NSAppTransportSecurity也可以工作,尽管我读到过完全禁用它会危及你的应用审查。

[编辑]我发现,简单地枚举我正在连接到的域在 NSExceptionDomains字典修复这个问题,即使当离开 NSExceptionAllowsInsecureHTTPLoads设置为真。:\

如果你只是针对特定的域名,你可以尝试把它添加到你的应用程序的 Info.plist 中:

<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>example.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>

当我将我的 HTTPS URL 指定为: https://www.mywebsite.com时,我会得到相同的错误。但是,当我指定它时,如果不使用三个 W 作为: https://mywebsite.com,那么它就可以正常工作。

Xcode project-> goto info.plist and Click + Button then Add (App Transport Security Settings) Xcode project-> goto info.plist and Click + Button then Add (App Transport Security Settings)展开,允许任意加载设置 YES。谢谢

我的问题是 NSURLConnection,这在 iOS9中被弃用了,所以我把所有的 API 都改成了 NSURLSession,这就解决了我的问题。

IOS9中不支持 NSURLConnection

在我的案例中,我在模拟器中遇到了这个问题,因为我的计算机日期落后于当前日期。因此,当您遇到 SSL 错误时,也要检查这种情况。

我在回放的时候出错了

finished with error [-1200] Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSErrorFailingURLStringKey=https://remote-abcabc-svc.an.abc.com:1935/abr/_definst_/smil:v2/video/492F2F82592F59EA74ABAA6B9D6E6F42/F6B1BD452132329FBACD32730862CAE0/091EAD80FE9BEDD52A2F33840CA3CBAC.v3.eng.smil/playlist.m3u8, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <692A1174-DA1C-4267-9560-9020A79F8458>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <692A1174-DA1C-4267-9560-9020A79F8458>

我确保在 plist 文件中的异常域中添加了条目,并且 NSAllows套用负载设置为 true,但是我仍然看到一个错误。

然后我意识到我正在使用 https 而不是 http 来播放 URL。

我把视频网址设置为 http,问题就解决了。

我得到这个错误的一些网络电话,而不是其他人。我连上了公共无线网。那个免费 wifi 似乎篡改了某些网址,因此出现了错误。

当我连接到 LTE 时,这个错误消失了!

使用这个站点,我输入了发出请求的服务器的地址,并将生成的 SHA 密钥添加到 info.plist。

Https://www.ssllabs.com/ssltest/index.html

<key>NSAppTransportSecurity</key>
<dict>
<key>NSPinnedDomains</key>
<dict>
<key>Your domain here (www.api.com)</key>
<dict>
<key>NSPinnedLeafIdentities</key>
<array>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>******pfbtB5iNouq********rC8Nrb+AmLFKxV7qgM=</string>
</dict>
</array>
</dict>
</dict>
</dict>

在我的案例中,我打开了诸如 Charles Proxy 或 Proxyman 之类的网络嗅探应用程序