Аутентификация сервера в Swift 2.0 и XCode 7 сломана

Я просто обновил свой код до Swift 2.0 для работы с Xcode 7. Мое приложение выполняет NSURLAuthenticationMethodServerTrust и NSURLAuthenticationMethodClientCertificate .

Проблема заключается в NSURLAuthenticationMethodServerTrust аутентификация NSURLAuthenticationMethodServerTrust перестала работать на моем симуляторе, но все же работает на моем тестовом устройстве с iOS 8.3. Помимо моего старого проекта, который не является Swift 2.0, также все еще работает.

Ошибка: Ошибка NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

Ошибка, полученная из NSURLSession:

 Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo=0x7fcf75053070 {NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fcf73700d00>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9802, NSUnderlyingError=0x7fcf735284b0 "The operation couldn't be completed. (kCFErrorDomainCFNetwork error -1200.)", NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://mywebapi/dosomething, NSErrorFailingURLStringKey=https://mywebapi/dosomething, _kCFStreamErrorDomainKey=3} [GetOneTimeTokenController.swift:76] 

Я все еще нацелен на iOS 8.0 для развертывания.

Вот как я обрабатываю вызов аутентификации (используя самоподписанный сертификат):

 if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { let urlCredential:NSURLCredential = NSURLCredential( identity: identityAndTrust.identityRef, certificates: identityAndTrust.certArray as [AnyObject], persistence: NSURLCredentialPersistence.ForSession); completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential); } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(trust: challenge.protectionSpace.serverTrust!)); } else { challenge.sender?.continueWithoutCredentialForAuthenticationChallenge(challenge) Logger.sharedInstance.logMessage("Unexpected Authentication Challange", .Error); } 

3 Solutions collect form web for “Аутентификация сервера в Swift 2.0 и XCode 7 сломана”

У вас нет обхода слоя TLS. Пожалуйста, найдите ответ ниже, который работал для меня, используя самоподписанный сертификат.

Ниже приведены изменения кода, которые отлично работают с сертификатом самоподписанного SSL

  func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) { let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust! let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)! let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))! let cerPath: String = NSBundle.mainBundle().pathForResource("xyz.com", ofType: "cer")! let localCertificateData = NSData(contentsOfFile:cerPath)! if (remoteCertificateData.isEqualToData(localCertificateData) == true) { let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust) challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge) completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)) } else { completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil) } } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")! let PKCS12Data = NSData(contentsOfFile:path)! let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data); let urlCredential:NSURLCredential = NSURLCredential( identity: identityAndTrust.identityRef, certificates: identityAndTrust.certArray as? [AnyObject], persistence: NSURLCredentialPersistence.ForSession); completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential); } else { completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil); } } struct IdentityAndTrust { var identityRef:SecIdentityRef var trust:SecTrustRef var certArray:AnyObject } func extractIdentity(certData:NSData) -> IdentityAndTrust { var identityAndTrust:IdentityAndTrust! var securityError:OSStatus = errSecSuccess let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")! let PKCS12Data = NSData(contentsOfFile:path)! let key : NSString = kSecImportExportPassphrase as NSString let options : NSDictionary = [key : "xyz"] //create variable for holding security information //var privateKeyRef: SecKeyRef? = nil var items : CFArray? securityError = SecPKCS12Import(PKCS12Data, options, &items) if securityError == errSecSuccess { let certItems:CFArray = items as CFArray!; let certItemsArray:Array = certItems as Array let dict:AnyObject? = certItemsArray.first; if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> { // grab the identity let identityPointer:AnyObject? = certEntry["identity"]; let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!; print("\(identityPointer) :::: \(secIdentityRef)") // grab the trust let trustPointer:AnyObject? = certEntry["trust"]; let trustRef:SecTrustRef = trustPointer as! SecTrustRef; print("\(trustPointer) :::: \(trustRef)") // grab the cert let chainPointer:AnyObject? = certEntry["chain"]; identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: chainPointer!); } } return identityAndTrust; } 

Изменения, внесенные в файл info.plist

  <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>NSExceptionDomains</key> <dict> <key>amazonaws.com.cn</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/> <key>NSThirdPartyExceptionMinimumTLSVersion</key> <string>TLSv1.0</string> </dict> <key>amazonaws.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/> <key>NSThirdPartyExceptionMinimumTLSVersion</key> <string>TLSv1.0</string> </dict> <key>xyz.com</key> <dict> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> <key>NSRequiresCertificateTransparency</key> <false/> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> <key>NSAllowsArbitraryLoads</key> <false/> </dict> </plist> 

Ваш симулятор, скорее всего, работает под управлением iOS 9. В iOS 9 применяется TLS 1.2. Если вы не используете его, ваши запросы не удастся.

Проверьте это сообщение для получения дополнительной информации.

Вы можете обойти его, поместив это в свой Info.plist :

 <key>NSAppTransportSecurity</key> <dict> <!--Include to allow all connections (DANGER)--> <key>NSAllowsArbitraryLoads</key> <true/> </dict> 

но это просто временное решение, пока вы не сможете реализовать TLS 1.2.

У меня была такая же проблема с iOS9 и xcode 7 Просто добавьте:

 <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> 

к файлу plist . Он работает, но это временное решение, пока вы не сможете реализовать TLS 1.2.

  • Слияние видео, но AVAssetExportSession никогда не завершается
  • Как реализовать общий блок try-try-catch, чтобы поймать все ошибки, которые бросаются на операцию
  • timeIntervalSinceReferenceDate vs timeIntervalSince1970 vs timeIntervalSinceNow
  • Swift: Как сделать гладкую инерцию после панорамирования (перетаскивания)?
  • Ошибка Xcode 7 каждый раз, когда я пытаюсь распечатать что-то в консоли отладчика
  • Ошибка приложения при изменении разрешения AddressBook в настройках
  • Как установить делегат панели поиска viewController с помощью расширения?
  • Как преобразовать общий криптокод из Objective-C в Swift?
  • Общий контроллер в swift 2.0 с использованием раскадровки
  • Как разрешить Тип выражения неоднозначен без дополнительного контекста для аудиозаписей в swift 2
  • Swift, пользовательский UIButton не работает, если щелкнуть
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.