Аутентификация сервера в 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.

  • Swift: использование расширения протокола приводит к тому, что «непризнанный селектор отправлен в экземпляр»
  • Добавить игра UIView в заднюю часть сцены в игре SpriteKit
  • Как получить углы с помощью GPUImageHarrisCornerDetectionFilter
  • Как отклонить viewController в ios с помощью Swift
  • Недопустимое предупреждение о файлах после обновления до Xcode 8 и преобразования синтаксиса из версии swift 2.3 в swift 3.0
  • Swift 2 - Xcode 7.0 Не удается получить доступ к сайту HTTPS с ненадежным SSL-сертификатом
  • Каркасы Cocoapods не устанавливаются должным образом
  • Как я могу исправить ошибку установки Realm для swift 2.0?
  • Swift 2.0: делегат не работает
  • UIPageViewController отстает от прокрутки из-за UITableView
  • Строка Swift 2.0 с подстрокойWithRange
  • Swift 2, метод 'setOn' с селектором Objective-C 'setOn:' конфликтует с setter для 'on' с тем же селектором Objective-C
  • Interesting Posts

    Есть ли какой-либо Apple api, такой как google Place Search API

    Если клавиатура не отменена, при использовании панели поиска изменение схемы диспетчера точек назначения

    Использование UITabBarController, но строка состояния охватывает вид

    отправить push-уведомление для ios для чата для автономного пользователя, openfire xmpp

    в чем цель «–no-use-binaries» в carthage

    Как указать разрешенные версии SSL / TLS в AFNetworking 2?

    Суммируйте значения, полученные из coreData и Display в разделе

    MPRemoteCommandCenter вызывает обработчик несколько раз в iOS

    Приложения iOS, созданные в Yosemite / Xcode 7.1.1, все еще работают на iOS 10 (iPhone7)?

    Реактивный какао: подписаться только на новые значения

    При использовании UINavigationController методы viewWillAppear или viewDidAppear моего контроллера не вызываются

    UIButton не регистрируется на ios7

    UITableViewCell горизонтальный пользовательский эффект swip-to-delete

    Выравнивание центра автозапуска x в результате бесконечной схемы компоновки на iPhone 6 Plus

    Циклическая зависимость в модуле «Дарвин»: Дарвин -> Медиалиб -> UIKit -> Дарвин

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.