XCode 7/iOS 9:如何为NSURLSession启用自签名证书

XCode 7/iOS 9:如何为NSURLSession启用自签名证书,ios,ios9,xcode7,nsurlsession,tls1.2,Ios,Ios9,Xcode7,Nsurlsession,Tls1.2,为了测试我的应用程序,我设置了一个带有TLS1.2的服务器Apache2.4.12和一个自签名证书。问题是,当我运行我的应用程序并尝试与本地服务器通信时,会出现以下错误: NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) nil Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and

为了测试我的应用程序,我设置了一个带有TLS1.2的服务器Apache2.4.12和一个自签名证书。问题是,当我运行我的应用程序并尝试与本地服务器通信时,会出现以下错误:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
nil
Optional(Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred  and a secure connection to the server cannot be made." UserInfo= {NSLocalizedDescription=An SSL error has occurred and a secure connection to the  server cannot be made., NSLocalizedRecoverySuggestion=Would you like to connect  to the server anyway?...
这是因为corse中的自签名证书不可靠。我在stackoverflow的某个地方读到,在我使用NSURLSession()的类中,我必须添加以下委托:

func URLSession(session: NSURLSession,
    task: NSURLSessionTask,
    didReceiveChallenge challenge: NSURLAuthenticationChallenge,
    completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?)
    -> Void) {

    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))
}
class LoginService: NSObject, NSURLSessionDelegate {

func URLSession(session: NSURLSession,
    task: NSURLSessionTask,
    didReceiveChallenge challenge: NSURLAuthenticationChallenge,
    completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?)
    -> Void) {

    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))
}

...
然后执行:

func requestLoginWithURL (requestURL: NSURL, completionHandler: (success: Bool?) -> Void) {
    let configuration =
    NSURLSessionConfiguration.defaultSessionConfiguration()

    let urlRequest: NSURLRequest = NSURLRequest(URL: requestURL)

    let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())

    /*
    dataTaskWithRequest: creates an HTTP request for the specified URL request object, and calls a handler upon completion.
    */
    let task = session.dataTaskWithRequest( ...)
}
但这似乎无论如何都不起作用。因此,我想知道是否有一种方法可以强制接受自分配证书,而无需将xml代码添加到info.plist以禁用任何形式的安全通信。 以下是我的服务器中的httpd-ssl.conf:

<VirtualHost *:443>
      DocumentRoot "/Applications/AMPPS/www"
      ServerName localhost
      SSLEngine on
      SSLProtocol all -SSLv2 -SSLv3
      SSLHonorCipherOrder on
      SSLCertificateFile "/Applications/AMPPS/apache/conf/server.crt"
      SSLCertificateKeyFile "/Applications/AMPPS/apache/conf/server.key"
</VirtualHost>
}

然后执行如下操作:

let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()

    let urlRequest: NSURLRequest = NSURLRequest(URL: requestURL)

    let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())

    /*
    dataTaskWithRequest: creates an HTTP request for the specified URL request object, and calls a handler upon completion.
    */
    let task = session.dataTaskWithRequest(urlRequest...)
这对我有用。请记住,您必须使用Apache2.4.x,因为它是唯一支持TLS1.2的版本。
希望这会有所帮助。

如果您使用的是自签名证书,您需要添加签名ca详细信息并信任它,或者禁用ATSb,但我正在阅读一些答案,其中谈到了诸如SetAllowsAnyHttpSceCertificate之类的原语,但它们是用objective-c编写的,我无法使用它们……所有这些内容都是在ATS之前的。您可以在更高级别的框架中禁用证书检查(如果他们执行证书检查,仍然需要这样做),但是ATS被嵌入到ios9中,并且在运行时不能被覆盖-如果您不想禁用它,您需要禁用它it info.plist。@Paulw11我不想禁用ATS。我想在Xcode7和is中添加自签名证书,并使用NSURLSession与服务器(在node.js中创建)建立HTTPS连接。您可以提供任何示例或文档吗?您需要将用于将服务器证书签名到iOS设备的CA公钥安装到iOS设备并信任它。如果您在iOS9中运行,那么如果启用ATS,则不受信任的证书将不起作用
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()

    let urlRequest: NSURLRequest = NSURLRequest(URL: requestURL)

    let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())

    /*
    dataTaskWithRequest: creates an HTTP request for the specified URL request object, and calls a handler upon completion.
    */
    let task = session.dataTaskWithRequest(urlRequest...)