如何使用iOS 7'接受自签名SSL证书;s NSURL会议

如何使用iOS 7'接受自签名SSL证书;s NSURL会议,ios,swift,ssl,https,self-signed,Ios,Swift,Ssl,Https,Self Signed,我有以下代码(swift实现): 它在iOS 8.x中运行良好,但在iOS 7.x中不起作用 在iOS 7.x中,我有一个错误: NSURLConnection/CFURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9813) 有什么想法吗? 谢谢你 无论是连接:canAuthenticateAgainstProtectionSpace:还是连接:didReceiveAuthenticationChallenge:在iOS 8中都不推荐使用,因此您应

我有以下代码(swift实现):

它在iOS 8.x中运行良好,但在iOS 7.x中不起作用 在iOS 7.x中,我有一个错误:

NSURLConnection/CFURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9813)

有什么想法吗?
谢谢你

无论是
连接:canAuthenticateAgainstProtectionSpace:
还是
连接:didReceiveAuthenticationChallenge:
在iOS 8中都不推荐使用,因此您应该使用其他方法

我在项目中使用的是NSURLSessionDelegate的委托方法。遵守该协议,然后添加此方法:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust))
}
然后,当使用initialize NSURLSession并将委托设置为self时。例如:

var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue:NSOperationQueue.mainQueue())
然后使用该会话实例在以下位置调用dataTaskWithRequest方法:

var task = session.dataTaskWithRequest(request){
    (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
    if error != nil {
        callback("", error.localizedDescription)
    } else {
        var result = NSString(data: data, encoding:
            NSASCIIStringEncoding)!
    }
}
task.resume()
可以找到完整的工作示例


出于安全原因,如果您使用自签名证书,我建议您也使用URLSessionLegate实现公钥固定()

继承类

创建会话对象

let config = URLSessionConfiguration.default


let session = Foundation.URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)


 let task = session.dataTask(with: httpRequest as URLRequest, completionHandler: {requestData, response, errorData -> Void in

            if errorData == nil {

                dataCallback(requestData! as NSData)
            }
            else {

                let error = NSError(domain: "Err-1001", code: 11, userInfo:nil)
                failureCallback(error)
            }
        });

        task.resume() 
添加委托方法

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive     challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
     completionHandler(
        .useCredential,
        URLCredential(trust: challenge.protectionSpace.serverTrust!))
 }
将此添加到info.plist文件中

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>xyc.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>
    </dict>
</dict>
NSAppTransportSecurity
NSExceptionDomains
xyc.com
n包括多个域
N异常低安全Http负载
NSExceptionRequiresForwardSecretary
NSExceptionMinimumTLSVersion
TLSv1.2
N第三方异常低安全Http负载
N第三方例外要求转发保密
第三方例外最小版本
TLSv1.2
NSRequiresCertificateTransparency

Swift 5解决方案

注意:这些设置仅用于测试目的,不要在生产应用程序中推送更改

步骤

  • 将“允许任意加载”键添加到info.plist中“应用程序传输安全设置”下的“是”

  • 创建新的会话对象,并将其委托给自己

    let config=URLSessionConfiguration.default
    let session=URLSession(配置:config,委托:self,delegateQueue:OperationQueue.main)

  • 将URLSessionLegate协议实现到当前类

    扩展类:urlsessionelegate{ func urlSession(session:urlSession,didReceive质询:URLAuthenticationChallenge,completionHandler:(urlSession.AuthChallengeDisposition,URLCredential?->Void){ completionHandler(URLSession.AuthChallengeDisposition.useCredential,URLCredential(信任:challenge.protectionSpace.serverTrust!)) } }

  • 修订版本:

    这在没有公钥锁定的情况下是安全的吗?据我所知,您不检查证书匹配,它应该检查什么?当您不使用公钥固定时,您如何检查证书匹配?密钥钉扎是不需要的,但我建议这就是为什么我把底部的链接包含到一个片段中……在没有使用公钥钉扎的情况下,流量仍然是加密的,但是我猜想中间人攻击(MITM)可以提供另一个证书来拦截流量。对我来说不起作用。“Error Domain=NSURERRORDOMAIN Code=-999”。但它可以使用有效的证书。@coyer-999错误表示请求被取消。可能是您或您使用的其他库取消了请求(请参阅)?或者服务器本身有问题(例如,证书是自签名的,但主机名也不正确)
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>xyc.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.2</string>
                <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
                <false/>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <true/>
                <key>NSThirdPartyExceptionMinimumTLSVersion</key>
                <string>TLSv1.2</string>
                <key>NSRequiresCertificateTransparency</key>
                <false/>
            </dict>
        </dict>
    </dict>