CFNetwork SSLHandshakeが失敗したiOS 9


207

iOS 9ベータ1を使用している人にこの問題が発生しましたか?

標準のNSURLConnectionを使用してWebサービスに接続し、Webサービスが呼び出されるとすぐに以下のエラーが発生します。これは現在iOS 8.3で動作しています

ベータバグの可能性はありますか?どんなアイデアや考えも素晴らしいでしょう!私はiOS 9開発のごく初期を知っています

ここに完全なエラーがあります:

CFNetwork SSLHandshakeが失敗しました(-9824)NSURLSession / NSURLConnection HTTPロードが失敗しました(kCFStreamErrorDomainSSL、-9824)

 NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://mywebserviceurl"]];
        NSURLResponse * response = nil;
        NSError * error = nil;
        NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest
                                                  returningResponse:&response
                                                              error:&error];

回答:


310

iOS 9およびOSX 10.11では、アプリのInfo.plistファイルで例外ドメインを指定しない限り、データをリクエストする予定のすべてのホストでTLSv1.2 SSLが必要です。

Info.plist構成の構文は次のようになります。

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow insecure HTTP requests-->
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

アプリケーション(サードパーティのWebブラウザなど)が任意のホストに接続する必要がある場合は、次のように構成できます。

<key>NSAppTransportSecurity</key>
<dict>
    <!--Connect to anything (this is probably BAD)-->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

これを行う必要がある場合は、TLSv1.2とSSLを使用するようにサーバーを更新することをお勧めします(まだ使用していない場合)。これは一時的な回避策と考える必要があります。

現在のところ、プレリリースのドキュメントでは、これらの構成オプションについて特定の方法で言及されていません。それができたら、関連するドキュメントにリンクするように回答を更新します。


1
App Transport Security(ATS)を使用すると、アプリは、安全な通信を必要とするドメインを指定するInfo.plistファイルに宣言を追加できます。ATSは、偶発的な開示を防ぎ、安全なデフォルトの動作を提供し、導入が簡単です。新しいアプリを作成しているか、既存のアプリを更新しているかに関係なく、できるだけ早くATSを採用する必要があります。新しいアプリを開発する場合は、HTTPSのみを使用する必要があります。既存のアプリがある場合は、できる限りHTTPSを使用し、残りのアプリをできるだけ早く移行するための計画を作成する必要があります。
user3099837

2
@StevenPetersonちょっとsteve例外ドメインの例が機能しないようですが、偶然アイデアがあります。コピーして.plistに貼り付けただけで、TLSv1.1がTLSv1.0に変更され、ドメインがhttpsなしでドメインに変更されました。 // etc
user3099837

27
長いチャットで申し訳ありませんが、<key> NSTemporaryExceptionRequiresForwardSecrecy </ key>を無効にする必要があることがわかりました。<false />
user3099837

2
@RashmiRanjanmallick NSTemporaryExceptionMinimumTLSVersionは、1.2以外のサーバーで作業していることをATSに伝えるために使用されます。たとえば、TLS 1.0を使用するホストに接続する場合は、これを使用します。上記のuser3099837で示したように、NSTemporaryExceptionRequiresForwardSecrecyをfalseに設定して使用する必要もあります。
Womble

2
ste.vn/2015/06/10/…-これは、回答の元となったブログです。
Sean Dev、2015

66

iOS 10以降では、TLS文字列は「TLSv1.0」の形式でなければなりません。単に「1.0」にすることはできません。(はぁ)


他の回答の次の組み合わせが機能します。

TLS 1.0しかないホスト(YOUR_HOST.COM)に接続しようとしているとしましょう。

これらをアプリのInfo.plistに追加します

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>YOUR_HOST.COM</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.0</string>
            <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>

9
追加するとNSTemporaryExceptionRequiresForwardSecrecyうまくいくようです、ありがとう!
Josh Valdivieso 2015年

2
このバージョンはiOS9.1では機能しませんでした-他の回答のいずれかでTLSVersion文字列形式を使用する必要がありました<key> NSTemporaryExceptionMinimumTLSVersion </ key> <string> TLSv1.1 </ string>
300baud

これは機能しますが、私の質問は、これらのパラメーターがオンでデータが暗号化されていない場合、アプリがsslを使用しないことを意味しますか?
theDC

33

詳細については、iOS 9およびOSX 10.11でApp Transport Securityの例外を構成する

不思議なことに、誤ってURLを誤って構成した可能性があるコードの誤りを防ぐために、接続がhttpプロトコルをhttpsに変更しようとしていることに気付くでしょう。場合によっては、これで実際に機能することもありますが、混乱を招く可能性もあります。

このApp Transport Securityを使用したアプリの配布では、いくつかの優れたデバッグのヒントを扱います

ATS失敗

ほとんどのATS障害は、-9800シリーズのコードでCFErrorとして示されます。これらはSecurity / SecureTransport.hヘッダーで定義されています

2015-08-23 06:34:42.700 SelfSignedServerATSTest[3792:683731] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

CFNETWORK_DIAGNOSTICS

障害に関するコンソールの詳細情報を取得するには、環境変数CFNETWORK_DIAGNOSTICSを1に設定します

nscurl

このツールは、ATS例外のいくつかの異なる組み合わせを実行し、各ATS構成で特定のホストへの安全な接続を試み、結果を報告します。

nscurl --ats-diagnostics https://example.com

1
nscurlはMac OS X "El Capitan"でのみ利用可能であるという唯一のポイント
webo80

1
一つは、より多くのTLS接続の暗号は、サーバーで使用されているか確認するには、先端のデバッグ:カール-vます。https:// <ホスト名>
アンドレ・Morujão

1
curl PASSがすべてのステップを正常に実行した場合、何が問題を引き起こす可能性があるかについてのアイデアはありますか?
アストン、

@ onmyway133「環境変数CFNETWORK_DIAGNOSTICSを1に設定する」方法について説明を追加できますか?
YakirNa 2016

1
@YakirNaあなたはここでそれを行う方法について読むことができますnshipster.com/launch-arguments-and-environment-variablesかなり簡単です:)
onmyway133

2

バックエンドが安全な接続Antを使用している場合は、NSURLSessionを使用します。

CFNetwork SSLHandshake failed (-9801)
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)

特にATSバージョンとSSL証明書情報を取得するには、サーバー構成を確認する必要があります。

を設定して安全でない接続を許可するだけNSExceptionAllowsInsecureHTTPLoads = YESでなく、サーバーがATSの最小要件(v1.2)を満たしていない場合(またはサーバー側を修正した方がよい場合)は、セキュリティの低下許可する必要があります。

単一サーバーへのセキュリティの低下を許可する

<key>NSExceptionDomains</key>
<dict>
    <key>api.yourDomaine.com</key>
    <dict>
        <key>NSExceptionMinimumTLSVersion</key>
        <string>TLSv1.0</string>
        <key>NSExceptionRequiresForwardSecrecy</key>
        <false/>
    </dict>
</dict>

opensslクライアントを使用して証明書を調査し、opensslクライアントを使用してサーバー構成を取得します。

openssl s_client  -connect api.yourDomaine.com:port //(you may need to specify port or  to try with https://... or www.)

..最後に見つける

SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: //
    Session-ID-ctx: 
    Master-Key: //
    Key-Arg   : None
    Start Time: 1449693038
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

App Transport Security(ATS)には、Transport Layer Security(TLS)プロトコルバージョン1.2が必要です。

ATSを使用して接続するための要件:

App Transport Security(ATS)を使用するためのWebサービス接続の要件には、サーバー、接続暗号、および証明書が含まれます。

証明書は、次のタイプの鍵のいずれかで署名されている必要があります。

  • ダイジェスト長が256以上のセキュアハッシュアルゴリズム2(SHA-2)キー(つまり、SHA-256以上)

  • サイズが256ビット以上の楕円曲線暗号(ECC)鍵

  • 長さが2048ビット以上のRivest-Shamir-Adleman(RSA)鍵無効な証明書は、ハード障害を引き起こし、接続されません。

次の接続暗号は、前方秘密(FS)をサポートし、ATSと連携します。

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

更新:opensslは最小限のプロトコルバージョンプロトコルのみを提供することが判明プロトコル:TLSv1 リンク


問題は、サーバーが要件を満たしているかどうかを確認するためにopenssl情報を解釈することが可能であるということです。またプロトコル:TLSv1は1.xではなくmakorバージョンである可能性があります
Idali

ポートを使用している場合に備えて、これを一般化します
Idali

答えは答えられるよりも多くの質問を開いたままにします。opensslレポートとAppleのドキュメントの対応関係に問題があるようです。openssl出力から、TLS 1.2がサポートされているかどうかを判別することはできません。また、この回答では、Perfect Forward Secrecyがサポートされているかどうかを判断できません。
zaph 2015

2

2日間の試行と失敗の後、私のために働いたのはこのウォンブルのコードです

変更点が1つあるため、この投稿によると、この種の規則のNSExceptionDomains辞書に関連付けられているサブキーの使用を停止する必要があります

  NSTemporaryExceptionMinimumTLSVersion

そして新しい大会で使用する

  NSExceptionMinimumTLSVersion

代わりに。

アップルのドキュメント

私のコード

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>YOUR_HOST.COM</key>
            <dict>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
                <key>NSExceptionMinimumTLSVersion</key>
                <string>TLSv1.0</string>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>

1

別の有用なツールはnmap(brew install nmap)です。

nmap --script ssl-enum-ciphers -p 443 google.com

出力を与える

Starting Nmap 7.12 ( https://nmap.org ) at 2016-08-11 17:25 IDT
Nmap scan report for google.com (172.217.23.46)
Host is up (0.061s latency).
Other addresses for google.com (not scanned): 2a00:1450:4009:80a::200e
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.0: 
|     ciphers: 
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.1: 
|     ciphers: 
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: server
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (secp256r1) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|     compressors: 
|       NULL
|     cipher preference: client
|_  least strength: C

Nmap done: 1 IP address (1 host up) scanned in 5.48 seconds

証明書の問題をデバッグするのに非常に便利
Lopakhin

0

このエラーは、バグのある/壊れやすいCordova iOSバージョンを使用しているときにログに表示されることがありました。Cordova iOSをアップグレードまたはダウングレードしたとき、それはなくなりました。

私が接続していたサーバーはTLSv1.2 SSLを使用していたので、それが問題ではないことがわかりました。


0

プロジェクト .plistファイルに次の権限を追加します。

<key>NSAppTransportSecurity</key>
<dict>
    <!--Connect to anything (this is probably BAD)-->
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

0

Info.plist構成の構文

   <key>NSAppTransportSecurity</key>
   <dict>
   <key>NSExceptionDomains</key>
    <dict>
    <key>yourserver.com</key>
   <dict>
  <!--Include to allow subdomains-->
  <key>NSIncludesSubdomains</key>
  <true/>
  <!--Include to allow insecure HTTP requests-->
  <key>NSExceptionAllowsInsecureHTTPLoads</key>
  <true/>
  <!--Include to specify minimum TLS version-->
  <key>NSExceptionMinimumTLSVersion</key>
  <string>TLSv1.1</string>
   </dict>
 </dict>


0

更新された回答(ポストWWDC 2016):

iOSアプリでは2016年末までに安全なHTTPS接続が必要になります。ATSをオフにしようとすると、アプリが将来拒否される可能性があります。

App Transport Security(ATS)は、AppleがiOS 9で導入した機能です。ATSを有効にすると、アプリは非セキュアHTTPではなくHTTPS接続を介してWebサービスに強制的に接続されます。

ただし、上記の回答で述べたように、開発者はATSをオフにして、アプリがHTTP接続経由でデータを送信することを許可できます。2016年末に、AppleはアプリをApp Storeに送信することを希望するすべての開発者にATSを必須にします。リンク


0

私がテストしたデバイスの時刻設定が間違っていました。したがって、証明書がすぐになくなるページにアクセスしようとすると、証明書の有効期限が切れていてもデバイスがアクセスを拒否します。修正するには、デバイスに適切な時間を設定してください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.