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 ...
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