CFNetwork SSLHandshake gagal iOS 9

207

Adakah yang memiliki iOS 9 beta 1 yang mengalami masalah ini?

Saya menggunakan NSURLConnection standar untuk terhubung ke layanan web dan segera setelah panggilan ke layanan web saya mendapatkan kesalahan di bawah ini. Ini sedang bekerja di iOS 8.3

Kemungkinan bug beta? ide atau pemikiran apa pun akan luar biasa! Saya tahu ini sangat awal dalam pengembangan iOS 9

Inilah kesalahan lengkapnya:

CFNetwork SSLHandshake gagal (-9824) NSURLSession / NSURLConnection HTTP load gagal (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];
pengguna3099837
sumber

Jawaban:

310

iOS 9 dan OSX 10.11 memerlukan TLSv1.2 SSL untuk semua host yang Anda rencanakan untuk meminta data dari kecuali Anda menentukan domain pengecualian di file Info.plist aplikasi Anda.

Sintaks untuk konfigurasi Info.plist terlihat seperti ini:

<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>

Jika aplikasi Anda (browser web pihak ketiga, misalnya) perlu terhubung ke host sewenang-wenang, Anda dapat mengonfigurasinya seperti ini:

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

Jika Anda harus melakukan ini, mungkin yang terbaik adalah memperbarui server Anda untuk menggunakan TLSv1.2 dan SSL, jika mereka belum melakukannya. Ini harus dianggap sebagai solusi sementara.

Sampai hari ini, dokumentasi pra-rilis tidak menyebutkan opsi konfigurasi ini dengan cara tertentu. Setelah itu, saya akan memperbarui jawaban untuk menautkan ke dokumentasi yang relevan.

Steven Peterson
sumber
1
App Transport Security (ATS) memungkinkan aplikasi menambahkan deklarasi ke file Info.plist-nya yang menentukan domain yang memerlukan komunikasi aman. ATS mencegah pengungkapan yang tidak disengaja, memberikan perilaku default yang aman, dan mudah diadopsi. Anda harus mengadopsi ATS sesegera mungkin, terlepas dari apakah Anda membuat aplikasi baru atau memperbarui yang sudah ada. Jika Anda mengembangkan aplikasi baru, Anda harus menggunakan HTTPS secara eksklusif. Jika Anda memiliki aplikasi yang ada, Anda harus menggunakan HTTPS sebanyak yang Anda bisa saat ini, dan membuat rencana untuk memigrasikan sisa aplikasi Anda sesegera mungkin.
user3099837
2
@StevenPeterson hei steve saya sepertinya tidak bisa mendapatkan contoh pengecualian domain untuk bekerja, apakah Anda memiliki ide secara kebetulan, saya hanya menyalin dan menempel ke .plist mengubah TLSv1.1 menjadi TLSv1.0 dan domain ke domain kami tanpa https: // etc
user3099837
27
Maaf untuk obrolan panjang tapi saya mengetahuinya saya perlu menonaktifkan <key> NST temporaryExceptionRequiresForwardSecrecy </key> <false />
user3099837
2
@RashmiRanjanmallick NSTemporaryExceptionMinimumTLSVersion digunakan untuk memberi tahu ATS bahwa Anda bekerja dengan server non 1.2. Misalnya, gunakan ini jika Anda mencoba untuk terhubung ke host yang menggunakan TLS 1.0. Anda juga harus menggunakan NST temporaryExceptionRequiresForwardSecrecy yang disetel ke false, seperti yang ditunjukkan oleh pengguna3099837 di atas.
Womble
2
ste.vn/2015/06/10/... - Ini adalah blog tempat jawabannya berasal.
Sean Dev
66

Di iOS 10+, string TLS HARUS dari bentuk "TLSv1.0". Tidak mungkin hanya "1.0". (Mendesah)


Kombinasi berikut dari Jawaban lainnya berfungsi.

Katakanlah Anda mencoba terhubung ke host (YOUR_HOST.COM) yang hanya memiliki TLS 1.0.

Tambahkan ini ke Info.plist aplikasi Anda

<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>
Womble
sumber
9
Tampaknya menambahkan NSTemporaryExceptionRequiresForwardSecrecymelakukan trik untuk saya, terima kasih!
Josh Valdivieso
2
Versi ini tidak berfungsi untuk saya di iOS9.1 - Saya perlu menggunakan format string TLSVersion di salah satu jawaban lain <key> NSTemporaryExceptionMinimumTLSVersion </key> <string> TLSv1.1 </string>
300baud
Ini berfungsi tetapi pertanyaan saya adalah: apakah itu berarti aplikasi saya tidak menggunakan ssl ketika parameter ini aktif dan data tidak dienkripsi?
theDC
33

Untuk info lebih lanjut Mengkonfigurasi Pengecualian Keamanan Transport Aplikasi di iOS 9 dan OSX 10.11

Anehnya, Anda akan melihat bahwa koneksi mencoba mengubah protokol http ke https untuk melindungi dari kesalahan dalam kode Anda di mana Anda mungkin telah salah mengkonfigurasi URL. Dalam beberapa kasus, ini mungkin benar-benar berhasil, tetapi juga membingungkan.

Ini Pengiriman Aplikasi dengan Keamanan Transportasi Aplikasi mencakup beberapa tips debugging yang baik

Kegagalan ATS

Kebanyakan kegagalan ATS akan muncul sebagai CFErrors dengan kode dalam seri -9800. Ini didefinisikan dalam header Security / SecureTransport.h

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

CFNETWORK_DIAGNOSTICS

Setel variabel lingkungan CFNETWORK_DIAGNOSTICS ke 1 untuk mendapatkan informasi lebih lanjut tentang konsol tentang kegagalan

nscurl

Alat ini akan dijalankan melalui beberapa kombinasi pengecualian ATS yang berbeda, mencoba koneksi aman ke host yang diberikan di bawah setiap konfigurasi ATS dan melaporkan hasilnya.

nscurl --ats-diagnostics https://example.com
onmyway133
sumber
1
Hanya titik bahwa nscurl hanya tersedia di Mac OS X "El Capitan"
webo80
1
Satu lagi tip debugging, untuk memeriksa cipher koneksi TLS mana yang sedang digunakan oleh server Anda: curl -v https: // <hostname>
André Morujão
1
Ada ide tentang apa yang dapat menyebabkan masalah jika ikal PASS semua langkah baik-baik saja?
Aston
@ onmyway133 dapatkah Anda menambahkan penjelasan tentang cara "Setel variabel lingkungan CFNETWORK_DIAGNOSTICS ke 1"?
YakirNa
1
@YakirNa Anda dapat membaca tentang cara melakukannya di sini nshipster.com/launch-arguments-and-environment-variables itu cukup mudah :)
onmyway133
2

Jika backend Anda menggunakan semut koneksi aman Anda bisa menggunakan NSURLSession

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

Anda perlu memeriksa konfigurasi server Anda terutama untuk mendapatkan versi ATS dan Info sertifikat SSL:

Alih-alih hanya Mengizinkan Koneksi Tidak Aman dengan menetapkan NSExceptionAllowsInsecureHTTPLoads = YES, alih-alih Anda perlu Izinkan Keamanan yang Rendah jika server Anda tidak memenuhi persyaratan minimum (v1.2) untuk ATS (atau lebih baik untuk memperbaiki sisi server).

Mengizinkan Keamanan yang Rendah ke Server Tunggal

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

gunakan klien openssl untuk menyelidiki sertifikat dan dapatkan konfigurasi server Anda menggunakan klien openssl:

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

..cari pada akhirnya

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) memerlukan protokol Transport Layer Security (TLS) versi 1.2.

Persyaratan untuk Menghubungkan Menggunakan ATS:

Persyaratan untuk koneksi layanan web untuk menggunakan App Transport Security (ATS) melibatkan server, cipher koneksi, dan sertifikat, sebagai berikut:

Sertifikat harus ditandatangani dengan salah satu dari jenis kunci berikut:

  • Kunci Secure Hash Algorithm 2 (SHA-2) dengan panjang intis minimal 256 (yaitu, SHA-256 atau lebih besar)

  • Kunci Elliptic-Curve Cryptography (ECC) dengan ukuran setidaknya 256 bit

  • Kunci Rivest-Shamir-Adleman (RSA) dengan panjang setidaknya 2048 bit. Sertifikat yang tidak valid menghasilkan kegagalan yang berat dan tidak ada koneksi.

Cipher koneksi berikut mendukung kerahasiaan penerusan (FS) dan bekerja dengan 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

Pembaruan: ternyata openssl hanya menyediakan versi protokol minimal Protokol: tautan TLSv1

Idali
sumber
pertanyaan yang tersisa adalah apakah mungkin untuk menginterpretasikan informasi openssl untuk mengetahui apakah server memenuhi persyaratan. Juga Protokol: TLSv1 mungkin merupakan versi pembuat bukan 1.x
Idali
Saya membuatnya umum, jika menggunakan port
Idali
Jawabannya membuat lebih banyak pertanyaan terbuka daripada dijawab. Tampaknya masalah mungkin adalah pemetaan antara apa yang membuka laporan dan dokumentasi Apple. Tidak mungkin dari keluaran openssl untuk menentukan apakah TLS 1.2 didukung. Jawabannya juga tidak memungkinkan untuk menentukan apakah Perfect Forward Secrecy didukung.
zaph
2

Setelah dua hari upaya dan kegagalan, yang berhasil bagi saya adalah kode womble ini

dengan One change, menurut posting ini kita harus berhenti menggunakan sub-kunci yang terkait dengan kamus NSExceptionDomains dari jenis Konvensi

  NSTemporaryExceptionMinimumTLSVersion

Dan gunakan di Konvensi baru

  NSExceptionMinimumTLSVersion

sebagai gantinya.

dokumentasi apel

kode saya

<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>
yehoni amran
sumber
1

Alat lain yang bermanfaat adalah nmap (brew install nmap)

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

Memberikan hasil

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
Ryan Heitner
sumber
sangat berguna untuk men-debug masalah sertifikat
Lopakhin
0

Kesalahan ini muncul di log kadang-kadang ketika saya menggunakan versi iOS Cordova buggy / crashy. Itu hilang ketika saya memutakhirkan atau menurunkan iOS Cordova.

Server tempat saya terhubung menggunakan TLSv1.2 SSL, jadi saya tahu itu bukan masalahnya.

im3r3k
sumber
0

Dalam .plistfile proyek Anda, tambahkan izin ini:

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

Sintaks untuk konfigurasi 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>

ALOK KUMAR
sumber
0

Jawaban Diperbarui (pasca-WWDC 2016):

Aplikasi iOS akan memerlukan koneksi HTTPS yang aman pada akhir 2016. Mencoba mematikan ATS dapat membuat aplikasi Anda ditolak di masa mendatang.

App Transport Security, atau ATS, adalah fitur yang diperkenalkan Apple di iOS 9. Ketika ATS diaktifkan, itu memaksa aplikasi untuk terhubung ke layanan web melalui koneksi HTTPS daripada HTTP yang tidak aman.

Namun, pengembang masih dapat mematikan ATS dan mengizinkan aplikasi mereka untuk mengirim data melalui koneksi HTTP seperti yang disebutkan dalam jawaban di atas. Pada akhir 2016, Apple akan membuat ATS wajib untuk semua pengembang yang berharap untuk mengirimkan aplikasi mereka ke App Store. tautan

Paraneetharan Saravanaperumal
sumber
0

Perangkat yang saya uji memiliki pengaturan waktu yang salah. Jadi ketika saya mencoba mengakses halaman dengan sertifikat yang akan segera habis itu akan menolak akses karena perangkat meskipun sertifikat telah kedaluwarsa. Untuk memperbaikinya, atur waktu yang tepat pada perangkat!

Warpzit
sumber