iOS 9.3: произошла ошибка SSL, и безопасное соединение с сервером не может быть установлено
Я получаю следующую ошибку с самозаверяющим сертификатом
ошибка домена=Nsurlerrordomain код=-1200 " произошла ошибка SSL и безопасное соединение с сервером невозможно.
во время тестирования веб-сервисов для одного из моих демо-приложений с
- iOS 9.3
- XCode 7.3
- Swift 2.2
- Alamofire 3.3.0
- и локальный сервер : https://filename.hostname.net
Примечание: прежде чем предполагать его дубликат, я бы попросил прочитать его полностью, даже то же самое, что я сообщил форумам Apple dev
используя Библиотека Alamofire
func testAlamofireGETRequest() -> Void
{
Alamofire.request(.GET, "https://filename.hostname.net/HelloWeb/service/greeting/john")
.responseJSON
{ response in
print("Response JSON: (response.result.value)")
}
}
используя NSURLSession
func testNSURLSessionRequest() -> Void {
let session = NSURLSession.sharedSession()
let urlString = "https://filename.hostname.net/HelloWeb/service/greeting/john"
let url = NSURL(string: urlString)
let request = NSURLRequest(URL: url!)
let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
print("done, error: (error)")
//Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made.
}
dataTask.resume()
}
Я провел 2 дня без везения : (
там куча вопросов уже размещена, но ничего не сработало для меня
- Транспортная безопасность заблокировала открытый текст HTTP
- iOS9 получение ошибки "произошла ошибка ssl, и безопасное соединение с сервером не может быть сделано"
- как загрузить HTTP-URL с включенной безопасностью транспорта приложений в iOS 9? [дубликат]
- CFNetwork SSLHandshake не удалось iOS 9
- как обрабатывать "CFNetwork SSLHandshake не удалось" в iOS
- создание HTTPS-запроса в iOS 9 с самозаверяющим сертификатом
- самозаверяющий сертификат ios9 и безопасность транспорта приложений
опубликовано Alamofire git выпуск
- ошибка "CFNetwork SSLHandshake failed (-9847)" при выполнении запроса без SSL #538
- Самозаверяющий сертификат не принимается #876
- как я могу подключить свой сервер как HTTPS с помощью самозаверяющего файла сертификата #977
мой информация.pist файл обновляется для настроек ATS таким образом
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>filename.hostname.net</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
между тем я могу получить ответ для
http://filename.hostname.net
и https://google.com
но не для https://filename.hostname.net
может ли кто-нибудь предложить мне, почему я не могу заставить это работать после огромных усилий?
4 ответов
Я предполагаю, что сервер, который вы пытаетесь подключить, имеет недействительные сертификаты или не соответствует стандартам iOS 9 для ECC, шифров и т. д.
Если вы используете высокоуровневые сетевые API-интерфейсы-NSURLSession, NSURLConnection или что-либо, расположенное поверх них, - у вас нет прямого контроля над набором шифров, предлагаемым клиентом. Эти API выбирают набор наборов шифров, используя собственную внутреннюю логику.
Если вы используя сетевые API более низкого уровня-CFSocketStream, через свои API NSStream и CFStream, и все, что ниже этого-вы можете явно выбрать набор наборов шифров, которые вы хотите использовать. Как это сделать, зависит от конкретного API.
стандартная практика-это:
создайте пару потоков
настройте его для TLS
получите безопасный транспортный контекст, используя kCFStreamPropertySSLContext собственность
настроить особые свойства в этом контексте
открыть потоки
вы можете увидеть пример этого в примере кода TLSTool. В частности, посмотрите на TLSToolServer класс, где вы можете увидеть именно эту последовательность.
в очень коротком контексте вы хотите настроить поток таким образом, чтобы он обходил безопасность, однако, в в случае Alamofire вы можете сделать это напрямую:
func bypassAuthentication() {
let manager = Alamofire.Manager.sharedInstance
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
var credential: NSURLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = NSURLSessionAuthChallengeDisposition.UseCredential
credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .CancelAuthenticationChallenge
} else {
credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
if credential != nil {
disposition = .UseCredential
}
}
}
return (disposition, credential)
}
}
дайте мне знать, если это помогает. Спасибо!
в командной строке OS X выполните следующие действия:
nscurl --ats-diagnostics https://filename.hostname.net --verbose
это скажет вам, какие комбинации настроек ATS позволят и не позволят iOS получить доступ к вашему сайту, и должно указать вам, что не так с вашим сайтом.
Это может быть один или несколько из следующих
- алгоритм хэша сертификата (должен быть SHA-256 или выше)
- версия TLS (должна быть 1.2)
- алгоритмы TLS (должны обеспечивать Совершенная Прямая Секретность)
Apple выпустила полный список требований для транспортной безопасности приложения.
оказалось, что мы работаем с TLS v1.2 но отсутствовали некоторые другие требования.
- TLS требует, по крайней мере, версия 1.2.
- шифры соединения ограничены к тем которые обеспечивают переднюю секретность (см. ниже для списка шифров.)
- услуги требуется сертификат, использующий по крайней мере отпечаток пальца SHA256 с битом 2048 или большим ключом RSA, или 256-битным или большим ключом эллиптической кривой (ECC).
- недопустимые сертификаты приводят к жесткому сбою и отсутствию соединения.
- принятые шифры:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
У меня был такой же сценарий и застрял на день. Попробуйте с вашими мобильными данными, если это хорошо работает с вашим API, то проблема с вашим сетевым брандмауэром. затем включите SSL / TLS из настроек брандмауэра.