2017-05-17 5 views
0

Ich benutze URLSession, um eine Get-Anfrage mit TLS 1.2-Protokoll und Zertifikate (die alle selbst signiert sind) im Hauptpaket enthalten. Ich habe das Pinning geschafft, aber der Server benötigt auch ein Client-Zertifikat für die Authentifizierung, also versuche ich auf AuthenticationChallenge mit UrlCredential zu antworten, aber es funktioniert nicht: Ich bekomme immer NSURLErrorDomain Code=-1206, was "Der Server" my_server_domain.it "erfordert ein Client-Zertifikat . "Swift 3 UrlSession mit Client-Authentifizierung durch Zertifikat

Hier ist meine Anfrage:

func makeGetRequest(){ 

    let configuration = URLSessionConfiguration.default 
    var request = try! URLRequest(url: requestUrl, method: .get) 

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

    let task = session.dataTask(with: request, completionHandler: { (data, response, error) in 

     print("Data = \(data)") 
     print("Response = \(response)") 
     print("Error = \(error)") 

    }) 

    task.resume() 
} 

URLSessionDelegate, wo ich auf die AuthenticationChallenge antworten:

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { 

    let authenticationMethod = challenge.protectionSpace.authenticationMethod 
    print("authenticationMethod=\(authenticationMethod)") 

    if authenticationMethod == NSURLAuthenticationMethodClientCertificate { 

     completionHandler(.useCredential, getClientUrlCredential()) 

    } else if authenticationMethod == NSURLAuthenticationMethodServerTrust { 

     let serverCredential = getServerUrlCredential(protectionSpace: challenge.protectionSpace) 
     guard serverCredential != nil else { 
      completionHandler(.cancelAuthenticationChallenge, nil) 
      return 
     } 
     completionHandler(.useCredential, serverCredential) 
    } 

} 

Server Zertifikat Pinning:

func getServerUrlCredential(protectionSpace:URLProtectionSpace)->URLCredential?{ 

    if let serverTrust = protectionSpace.serverTrust { 
     //Check if is valid 
     var result = SecTrustResultType.invalid 
     let status = SecTrustEvaluate(serverTrust, &result) 
     print("SecTrustEvaluate res = \(result.rawValue)") 

     if(status == errSecSuccess), 
      let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) { 
       //Get Server Certificate Data 
       let serverCertificateData = SecCertificateCopyData(serverCertificate) 
       //Get Local Certificate NSData 
       let localServerCertNSData = certificateHelper.getCertificateNSData(withName: "localServerCertName", andExtension: "cer") 

       //Check if certificates are equals, otherwhise pinning failed and return nil 
       guard serverCertificateData == localServerCertNSData else{ 
        print("Certificates doesn't match.") 
        return nil 
       } 

       //Certificates does match, so we can trust the server 
       return URLCredential(trust: serverTrust) 
     } 
    } 

    return nil 

} 

Und hier ist, wo ich die erhalten Client URLCredential aus dem PKCS12 (.pfx) -Zertifikat:

Beachten Sie, dass func 'extractIdentityAndTrust' - erfolgreich eine Struktur mit Zeigern auf die Identität, Zertifikatskette und Vertrauensstellung zurückgibt, die aus dem PKCS12 extrahiert wurden; Ich weiß, dass Identität und Zertifikate im Schlüsselbund gespeichert werden sollten, aber im Moment nehme ich sie nur in das Paket auf, hauptsächlich weil die Dokumentation für den Schlüsselbund alles andere als gut ist.

Ich habe auch hinzugefügt App Transport Security Settings meiner Info.plist Datei like this

Es ist wie Client sucht versucht nicht einmal zu authentifizieren, also bin ich etwas fehlt, ich denke ...

+0

Hallo Kashish, hast du es geschafft, eine Antwort darauf zu bekommen? Ich bin auch beeindruckt von einer ähnlichen Situation, in der das Leben bei NSURLAuthenticationMethodServerTrust aufhört. – user550088

Antwort

0

Wenn Ihre getClientCredential() - Funktion aufgerufen wird, versucht Ihr Client, sich zu authentifizieren. Wenn nicht, dann könnten die Serverprotokolle (wie /var/log/nginx/access.log) den Grund angeben.

Die PKCS12-Klasse in this answer arbeitete für mich.

Schlüsselbund In Bezug auf this Apple documentation sagen

Um digitale Identitäten in Ihren eigenen Anwendungen zu verwenden, müssen Sie Code schreiben, um sie zu importieren. Dies bedeutet in der Regel das Lesen eines PKCS # 12-formatierten Blobs und das anschließende Importieren des Inhalts des Blobs in den Schlüsselbund der App mithilfe der Funktion "SecPKCS12Import", die im Zertifikat-, Schlüssel- und Vertrauensstellungsreferenzdokument dokumentiert ist.

Auf diese Weise werden Ihre neuen Schlüsselbundelemente mit der Schlüsselbundzugriffsgruppe Ihrer App erstellt.

Verwandte Themen