web-dev-qa-db-ja.com

iOS 8でアプリのSSL接続が切断されました-CFNetwork SSLHandshake failed(-9806)

私のアプリは単にホームデバイス上のWebサーバーに接続し、htmlを読み取ります。 httpを使用すると正常に機能しますが、iOS 8ではhttpsを使用すると機能しなくなりました。

AFNetworking v1を使用し、これらのオーバーライドメソッドを使用してSSLチェックをオーバーライドします(はい、通常の状況ではこれを行うべきではなく、安全ではないことなどは知っていますが、別のトピックです)。

[self setAuthenticationChallengeBlock:^(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge) {
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
            [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
        }
    }];

[self setAuthenticationAgainstProtectionSpaceBlock:^BOOL(NSURLConnection *connection, NSURLProtectionSpace *protectionSpace) {
        if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) {
                return YES; // Self-signed cert will be accepted
        }
        // If no other authentication is required, return NO for everything else
        // Otherwise maybe YES for NSURLAuthenticationMethodDefault and etc.
        return NO;
    }];

IOS 8では、次のようなエラーが表示されます。

CFNetwork SSLHandshakeが失敗しました(-9806)

CFNetwork SSLHandshakeが失敗しました(-9806)

CFNetwork SSLHandshakeが失敗しました(-9806)

NSURLConnection/CFURLConnection HTTPロードが失敗しました(kCFStreamErrorDomainSSL、-9806)

接続中のエラー:Error Domain = NSURLErrorDomain Code = -1200 "SSLエラーが発生し、サーバーへの安全な接続を確立できません。" UserInfo = 0x7b66c110 {NSLocalizedDescription = SSLエラーが発生し、サーバーへの安全な接続を確立できません。NSLocalizedRecoverySuggestion=サーバーに接続しますか?、_ kCFStreamErrorCodeKey = -9806、NSErrorFailingURLStringKey = https:/ /xxx.xxx.xxx.xxx:443/live.htm 、_kCFStreamErrorDomainKey = 3、NSUnderlyingError = 0x7c0d8a20「SSLエラーが発生し、サーバーへの安全な接続を確立できません。」、NSErrorFailingURLKey = https://xxx.xxx.xxx.xxx:443/Info.live.htm }

FSNetworkingに切り替えてみましたが、これを設定するとsometimesが機能します:

- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {

    if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust])
    {
        NSLog(@"Ignoring SSL");
        SecTrustRef trust = challenge.protectionSpace.serverTrust;
        NSURLCredential *cred;
        cred = [NSURLCredential credentialForTrust:trust];
        [challenge.sender useCredential:cred forAuthenticationChallenge:challenge];
        return;
    }
}

ただし、2つの同時要求を行うと、1つだけが成功し、1つは上記と同様のエラーで失敗します。 1つのリクエストのみがSSLオーバーライドポイントに到達しているようです。

誰かがこれにいくらかの光を当てて、これを破るためにiOS 8で何が変わったのか、そしてどのようにそれを修正することができますか?

ありがとう

14
Darren

IOS 8でも同じような問題に遭遇しました。

シナリオ:

  1. Httpsサーバーへの呼び出し
  2. UIWebViewにあるサーバーからhttps URLを開きます
  3. 将来のすべてのNSURLConnectionsはSSLHandshakeエラーで失敗します

useCredential:forAuthenticationChallengeがSecTrust *メソッドを呼び出した直後にこのエラーを引き起こしていました(ただし、同じサーバーでホストされているhttpsでページを開いた後のみ)。

このコードはエラーを引き起こしました:

[challenge.sender useCredential:urlCredential forAuthenticationChallenge:challenge];
SecTrustRef trustRef = [[challenge protectionSpace] serverTrust];
CFIndex count = SecTrustGetCertificateCount(trustRef);

しかし、これはしませんでした:

SecTrustRef trustRef = [[challenge protectionSpace] serverTrust];
CFIndex count = SecTrustGetCertificateCount(trustRef);
[challenge.sender useCredential:urlCredential forAuthenticationChallenge:challenge];

IOS 8ではSSLHandshakeが失敗し、iOS 7では失敗しなかった理由は明らかではありません。おそらくAFNetworkingはuseCredential:forAuthenticationChallengeこれは同じ問題を引き起こしています。

9
Simon Watiau

表示されているエラーは、SecureTransport.h。これはトランスポートレベルのエラーです。接続は中止されたため失敗しました。

クライアントとサーバーの両方で、多くのことが原因である可能性があります。これは、サーバーがクライアントに証明書を要求しており、クライアントが証明書を提供していない場合に発生する可能性が高く、その時点でサーバーは放棄を決定します。サーバーがクライアントに証明書を要求している場合、デリゲートメソッドは、サーバーの信頼に加えてクライアント証明書を使用した認証の試行を確認する必要があります。

2
quellish