iOS 9.3:发生 SSL 错误,无法与服务器建立安全连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36331623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS 9.3 : An SSL error has occurred and a secure connection to the server cannot be made
提问by swiftBoy
I am getting following error with self signed certificate
我在使用自签名证书时遇到以下错误
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made.
错误域=NSURLErrorDomain 代码=-1200 “发生 SSL 错误,无法与服务器建立安全连接。
while testing web-services for one of my demo app with
在为我的演示应用程序之一测试 Web 服务时
- iOS 9.3
- XCode 7.3
- Swift 2.2
- Alamofire 3.3.0
- and Local server : https://filename.hostname.net
- iOS 9.3
- 代码 7.3
- 斯威夫特 2.2
- 阿拉莫火 3.3.0
- 和本地服务器:https: //filename.hostname.net
Note:before assuming its Duplicate, I would request please read it all the way,even same i have reported to apple dev forums
注意:在假设它是重复的之前,我会要求请一直阅读它,即使我已经向苹果开发论坛报告过
Using Alamofire Library
使用Alamofire 库
func testAlamofireGETRequest() -> Void
{
Alamofire.request(.GET, "https://filename.hostname.net/HelloWeb/service/greeting/john")
.responseJSON
{ response in
print("Response JSON: \(response.result.value)")
}
}
Using NSURLSession
使用NSURLSession
func testNSURLSessionRequest() -> Void {
let session = NSURLSession.sharedSession()
let urlString = "https://filename.hostname.net/HelloWeb/service/greeting/john"
let url = NSURL(string: urlString)
let request = NSURLRequest(URL: url!)
let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
print("done, error: \(error)")
//Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made.
}
dataTask.resume()
}
I spent 2 days with no luck :(
there are bunch of questions already posted but nothing worked for me
我花了两天没有运气:(
已经发布了一堆问题,但对我没有任何帮助
- Transport Security has Blocked a cleartext HTTP
- iOS9 getting error “an ssl error has occurred and a secure connection to the server cannot be made”
- How do I load an HTTP URL with App Transport Security enabled in iOS 9? [duplicate]
- CFNetwork SSLHandshake failed iOS 9
- How to handle “CFNetwork SSLHandshake failed” in iOS
- Making HTTPS request in iOS 9 with self-signed certificate
- ios9 self signed certificate and app transport security
- 传输安全已阻止明文 HTTP
- iOS9 出现错误“发生了 ssl 错误,无法与服务器建立安全连接”
- 如何在 iOS 9 中启用应用传输安全性加载 HTTP URL?[复制]
- CFNetwork SSLHandshake 失败 iOS 9
- 如何在 iOS 中处理“CFNetwork SSLHandshake failed”
- 使用自签名证书在 iOS 9 中发出 HTTPS 请求
- ios9 自签名证书和应用程序传输安全
posted Alamofire git issue
发布了 Alamofire git 问题
- 'CFNetwork SSLHandshake failed (-9847)' error when performing a non-SSL request #538
- Self-Signed Certificate not accepted #876
- how can I connecting my server as HTTPS with using self-signed Certificate file #977
- 执行非 SSL 请求时出现“CFNetwork SSLHandshake failed (-9847)”错误 #538
- 不接受自签名证书 #876
- 如何使用自签名证书文件将我的服务器连接为 HTTPS #977
My Info.pistfile is updated for ATS settings this way
我的Info.pist文件以这种方式针对 ATS 设置进行了更新
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>filename.hostname.net</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
Meanwhile I am able to get response for
同时我能够得到回应
http://filename.hostname.net
http://文件名.主机名.net
and https://google.com
和HTTPS://google.com
butnot for https://filename.hostname.net
但不是HTTPS://filename.hostname.net
Can anyone please suggest me why I am not able to get this working after huge efforts?
任何人都可以建议我为什么经过巨大努力后我无法完成这项工作吗?
回答by yaakov
At the command-line in OS X, run the following:
在 OS X 的命令行中,运行以下命令:
nscurl --ats-diagnostics https://filename.hostname.net --verbose
nscurl --ats-diagnostics https://filename.hostname.net --verbose
This will tell you what combinations of ATS settings will and will not permit iOS to access your site, and should point you towards what is wrong with your site.
这将告诉您哪些 ATS 设置组合将允许和不允许 iOS 访问您的站点,并应指出您的站点有什么问题。
It could be one or more of the following
它可能是以下一项或多项
- Certificate hash algorithm (must be SHA-256 or above)
- TLS version (must be 1.2)
- TLS algorithms (must provide Perfect Forward Secrecy)
- 证书哈希算法(必须是SHA-256或以上)
- TLS 版本(必须是 1.2)
- TLS 算法(必须提供完美的前向保密)
回答by TechnicalTophat
Apple has released the full requirements list for the App Transport Security.
Apple 已经发布了 App Transport Security 的完整要求列表。
Turned out that we were working with TLS v1.2 but were missing some of the other requirements.
原来我们正在使用 TLS v1.2,但缺少一些其他要求。
- TLS requires at least version 1.2.
- Connection ciphers are limited to those that provide forward secrecy (see below for the list of ciphers.)
- The service requires a certificate using at least a SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256bit or greater Elliptic-Curve (ECC) key.
- Invalid certificates result in a hard failure and no connection.
- The accepted ciphers are:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- TLS 至少需要 1.2 版。
- 连接密码仅限于提供前向保密的密码(请参阅下面的密码列表。)
- 该服务需要至少使用 SHA256 指纹和 2048 位或更高的 RSA 密钥,或者 256 位或更高的椭圆曲线 (ECC) 密钥的证书。
- 无效的证书会导致硬故障和无连接。
- 接受的密码是:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
回答by Fennec
I presume the server you are trying to connect has invalid certificates or doesn't match up with the iOS 9 standards for ECC, Ciphers etc.
我认为您尝试连接的服务器的证书无效或与 ECC、密码等的 iOS 9 标准不匹配。
If you're using high-level networking APIs—NSURLSession, NSURLConnection, or anything layered on top of those—you don't have direct control over the cypher suites offered by the client. Those APIs choose a set of cypher suites using their own internal logic.
If you're using lower-level networking APIs—CFSocketStream, via its NSStream and CFStream APIs, and anything lower than that—you can explicitly choose the set of cypher suites you want to use. How you do this depends on the specific API.
如果您使用的是高级网络 API——NSURLSession、NSURLConnection 或任何位于这些 API 之上的东西——您无法直接控制客户端提供的密码套件。这些 API 使用自己的内部逻辑选择一组密码套件。
如果您使用的是较低级别的网络 API——CFSocketStream,通过其 NSStream 和 CFStream API,以及任何低于它的东西——您可以明确选择要使用的密码套件集。您如何执行此操作取决于特定的 API。
The standard practice is:
标准做法是:
create the stream pair
configure it for TLS
get the Secure Transport context using the kCFStreamPropertySSLContext property
configure specific properties in that context
open the streams
创建流对
为 TLS 配置它
使用 kCFStreamPropertySSLContext 属性获取安全传输上下文
在该上下文中配置特定属性
打开溪流
You can see an example of this in the TLSTool sample code. Specifically, look at the TLSToolServerclass, where you can see exactly this sequence.
您可以在 TLSTool 示例代码中看到这样的示例。具体来说,查看TLSToolServer类,您可以在其中准确看到此序列。
In a very short context, you want to configure the stream in such a way that it bypasses the security, however, in the case of Alamofire you can do this directly by:
在一个非常简短的上下文中,您希望以绕过安全性的方式配置流,但是,在 Alamofire 的情况下,您可以通过以下方式直接执行此操作:
func bypassAuthentication() {
let manager = Alamofire.Manager.sharedInstance
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
var credential: NSURLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = NSURLSessionAuthChallengeDisposition.UseCredential
credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .CancelAuthenticationChallenge
} else {
credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
if credential != nil {
disposition = .UseCredential
}
}
}
return (disposition, credential)
}
}
let me know if that helps. Thank you!
如果这有帮助,请告诉我。谢谢!
回答by Hasya
I had same scenario and got stuck for a day. Try with your mobile data, if this works fine with your API, then problem with your network firewall. then enable SSL / TLS from firewall settings.
我有同样的场景并被卡住了一天。尝试使用您的移动数据,如果这适用于您的 API,则说明您的网络防火墙有问题。然后从防火墙设置启用 SSL / TLS。