web-dev-qa-db-ja.com

iOS 9.3:SSLエラーが発生し、サーバーへの安全な接続を確立できません

自己署名証明書で次のエラーが発生します

Error Domain = NSURLErrorDomain Code = -1200 "SSLエラーが発生し、サーバーへの安全な接続を確立できません。

デモアプリの1つでWebサービスをテストしながら

注:その複製を仮定する前に、私がApple開発フォーラム

Alamofire Libraryを使用する


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日間過ごしました:(

すでに投稿された質問がたくさんありますが、私にとっては何もうまくいきませんでした

alamofire git issueを投稿しました


私のInfo.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

buthttps://filename.hostname.net

誰も私がなぜ多大な努力の後にこれを機能させることができないのか教えてください。

22
swiftBoy

OS Xのコマンドラインで、次を実行します。

nscurl --ats-diagnostics https://filename.hostname.net --verbose

これにより、ATS設定のどの組み合わせがiOSがサイトにアクセスすることを許可するか、許可しないかがわかり、サイトの何が問題なのかがわかります。

次の1つ以上の可能性があります。

  • 証明書ハッシュアルゴリズム(SHA-256以上である必要があります)
  • TLSバージョン(1.2である必要があります)
  • TLSアルゴリズム(Perfect Forward Secrecyを提供する必要があります)
41
yaakov

AppleはApp Transport Securityの完全な要件リストをリリースしました。

TLS v1.2で作業していたが、他の要件の一部が欠落していることが判明しました。

ここに完全なチェックリストがあります

  • TLSには少なくともバージョン1.2が必要です。
  • 接続暗号は、前方秘匿性を提供するものに限定されます(暗号のリストについては以下を参照してください)。
  • このサービスには、少なくとも2048ビット以上のRSAキー、または256ビット以上の楕円曲線(ECC)キーのいずれかのSHA256指紋を使用した証明書が必要です。
  • 証明書が無効な場合、ハード障害が発生し、接続できなくなります。
  • 受け入れられる暗号は次のとおりです。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
8
TechnicalTophat

接続しようとしているサーバーに無効な証明書があるか、ECCや暗号などのiOS 9標準と一致しないと思います。

  • NSURLSession、NSURLConnection、またはそれらの上に階層化されたものなど、高レベルのネットワークAPIを使用している場合、クライアントが提供する暗号スイートを直接制御することはできません。これらのAPIは、独自の内部ロジックを使用して一連の暗号スイートを選択します。

  • 下位レベルのネットワーキングAPI(NSStreamおよびCFStream APIを介したCFSocketStream、およびそれより低いもの)を使用している場合、使用する一連の暗号スイートを明示的に選択できます。これを行う方法は、特定のAPIによって異なります。

標準的なプラクティスは次のとおりです。

  1. ストリームペアを作成する

  2. tLS用に構成する

  3. kCFStreamPropertySSLContextプロパティを使用してセキュアトランスポートコンテキストを取得する

  4. そのコンテキストで特定のプロパティを構成する

  5. ストリームを開きます

この例は、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)
        }
    }

それが役立つかどうか教えてください。ありがとうございました!

5
Fennec

私は同じシナリオを持っていて、1日動けなくなった。モバイルデータで試してください。これがAPIで問題なく機能する場合は、ネットワークファイアウォールに問題があります。次に、ファイアウォール設定からSSL/TLSを有効にします。

4
Hasya