2015-06-09 11 views
15

mit habe ich den folgenden Code (schnelle Umsetzung):Wie nehme ich ein selbst signiertes SSL-Zertifikat iOS 7s NSURLSession

func connection(connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: NSURLProtectionSpace) -> Bool 
{ 
    return protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust 
} 

func connection(connection: NSURLConnection, didReceiveAuthenticationChallenge challenge: NSURLAuthenticationChallenge) 
{ 
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust 
    { 

     if challenge.protectionSpace.host == "myDomain" 
     { 
      let credentials = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust) 
      challenge.sender.useCredential(credentials, forAuthenticationChallenge: challenge) 
     } 
    } 

    challenge.sender.continueWithoutCredentialForAuthenticationChallenge(challenge) 

} 

Es funktioniert perfekt in iOS 8.x aber nicht funktioniert iOS 7 .x In iOS 7.x habe ich Fehler:

NSURLConnection/CFURLConnection HTTP Last fehlgeschlagen (kCFStreamErrorDomainSSL, -9813)

Jede Idee? danke !!!

Antwort

21

Sowohl connection:canAuthenticateAgainstProtectionSpace: als auch connection:didReceiveAuthenticationChallenge: sind in iOS 8 sowieso veraltet, daher sollten Sie andere Methoden verwenden.

Was ich in meinen Projekten verwende, ist eine Delegate-Methode von NSURLSessionDelegate. Halten Sie sich an dieses Protokoll dann diese Methode hinzufügen:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) { 
    completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust)) 
} 

Dann, wenn Sie initialisieren verwenden NSURLSession mit Delegaten selbst gesetzt. Zum Beispiel:

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

dann, dass Session-Instanz verwenden dataTaskWithRequest Methode aufzurufen:

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() 

komplette Arbeitsbeispiel gefunden werden here können.

Aus Sicherheitsgründen, wenn Sie ein selbst signiertes Zertifikat Ich empfehle auch Public-Key-Pinning (https://gist.github.com/edwardmp/df8517aa9f1752e73353)

+0

edwardmp Dank, funktioniert perfekt: D –

+0

Ist das überhaupt sicher ohne öffentlichen Schlüssel Pinning? Soweit ich sehen kann, überprüfen Sie nicht das Zertifikat entspricht, was es sollte –

+0

Wie können Sie die Übereinstimmungen des Zertifikats überprüfen, wenn Sie keine öffentlichen Schlüssel Pinning verwenden? Key-Pinning ist nicht erforderlich, aber ich empfehle es, das ist, warum ich den Link an der Unterseite zu einem Snippet enthalten .. – edwardmp

0

vererben Klasse mit URLSessionDelegate

erstellen ein Sitzungsobjekt

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() 

Add Umsetzung Delegierter Methad

func urlSession(_ session: URLSession, task: URLSessionTask, didReceive  challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { 
    completionHandler(
     .useCredential, 
     URLCredential(trust: challenge.protectionSpace.serverTrust!)) 
} 

dies in Ihrer Datei 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> 
Verwandte Themen