CFNetwork SSLHandshake thất bại iOS 9


207

Có ai với iOS 9 beta 1 có vấn đề này không?

Tôi sử dụng kết nối NSURLC tiêu chuẩn để kết nối với dịch vụ web và ngay khi có cuộc gọi đến dịch vụ web, tôi nhận được lỗi dưới đây. Điều này hiện đang hoạt động trong iOS 8.3

Lỗi beta có thể xảy ra? bất kỳ ý tưởng hoặc suy nghĩ sẽ là tuyệt vời! Tôi biết nó rất sớm trong quá trình phát triển iOS 9

Đây là lỗi đầy đủ:

CFNetwork SSLHandshake không thành công (-9824) Tải HTTP HTTP NSURLSession / NSURLC không thành công (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];

Câu trả lời:


310

iOS 9 và OSX 10.11 yêu cầu SSL TLSv1.2 cho tất cả các máy chủ bạn dự định yêu cầu dữ liệu trừ khi bạn chỉ định các miền ngoại lệ trong tệp Info.plist của ứng dụng.

Cú pháp cho cấu hình Info.plist trông như thế này:

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

Nếu ứng dụng của bạn (chẳng hạn như trình duyệt web của bên thứ ba) cần kết nối với các máy chủ tùy ý, bạn có thể định cấu hình như thế này:

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

Nếu bạn phải làm điều này, có lẽ tốt nhất là cập nhật máy chủ của bạn để sử dụng TLSv1.2 và SSL, nếu họ chưa làm như vậy. Điều này nên được coi là một cách giải quyết tạm thời.

Cho đến ngày hôm nay, tài liệu phát hành trước không đề cập đến bất kỳ tùy chọn cấu hình nào theo bất kỳ cách cụ thể nào. Khi có, tôi sẽ cập nhật câu trả lời để liên kết đến tài liệu liên quan.


1
Ứng dụng bảo mật vận chuyển (ATS) cho phép ứng dụng thêm một khai báo vào tệp Info.plist chỉ định các miền mà nó cần liên lạc an toàn. ATS ngăn chặn tiết lộ ngẫu nhiên, cung cấp hành vi mặc định an toàn và dễ dàng chấp nhận. Bạn nên áp dụng ATS càng sớm càng tốt, bất kể bạn đang tạo ứng dụng mới hay cập nhật ứng dụng hiện có. Nếu bạn đang phát triển một ứng dụng mới, bạn nên sử dụng HTTPS độc quyền. Nếu bạn có một ứng dụng hiện có, bạn nên sử dụng HTTPS càng nhiều càng tốt ngay bây giờ và tạo một kế hoạch để di chuyển phần còn lại của ứng dụng càng sớm càng tốt.
dùng3099837

2
@StevenPeterson hey steve tôi dường như không thể lấy ví dụ về trường hợp ngoại lệ, bạn có ý tưởng nào không, tôi chỉ sao chép và dán vào .plist đã thay đổi TLSv1.1 thành TLSv1.0 và tên miền thành tên miền của chúng tôi mà không có https: // vv
user3099837

27
Xin lỗi vì đã trò chuyện lâu nhưng tôi đã hiểu ra rằng tôi cần phải tắt <key> NST tạmExceptionRequiresForwardSecrecy </ key> <false />
user3099837

2
@RashmiRanjanmallick NST tạmExceptionMinimumTLSVersion được sử dụng để nói với ATS rằng bạn đang làm việc với máy chủ không 1.2. Ví dụ: sử dụng điều này nếu bạn đang cố gắng kết nối với máy chủ sử dụng TLS 1.0. Bạn cũng phải sử dụng NST tạmExceptionRequiresForwardSecrecy được đặt thành false, như user3099837 đã chỉ ra ở trên.
Womble

2
ste.vn/2015/06/10/ từ - Đây là blog nơi câu trả lời có nguồn gốc từ.
Sean Dev

66

Trong iOS 10+, chuỗi TLS PHẢI có dạng "TLSv1.0". Nó không thể chỉ là "1.0". (Thở dài)


Sự kết hợp sau đây của các câu trả lời khác hoạt động.

Giả sử bạn đang cố gắng kết nối với máy chủ lưu trữ (YOU_HOST.COM) chỉ có TLS 1.0.

Thêm chúng vào Info.plist của ứng dụng của bạn

<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
Có vẻ như thêm NSTemporaryExceptionRequiresForwardSecrecyđã lừa tôi, cảm ơn!
Josh Valdivieso

2
Phiên bản này không hoạt động với tôi trên iOS9.1 - Tôi cần sử dụng định dạng chuỗi TLSVersion trong một trong những câu trả lời khác <key> NST tạmExceptionMinimumTLSVersion </ key> <string> TLSv1.1 </ string>
300baud

Điều này hoạt động nhưng câu hỏi của tôi là: điều đó có nghĩa là ứng dụng của tôi không sử dụng ssl khi các tham số này được bật và dữ liệu không được mã hóa?
DC

33

Để biết thêm thông tin Định cấu hình ngoại lệ bảo mật vận chuyển ứng dụng trong iOS 9 và OSX 10.11

Thật kỳ lạ, bạn sẽ nhận thấy rằng kết nối cố gắng thay đổi giao thức http thành https để bảo vệ chống lại các lỗi trong mã của bạn, nơi bạn có thể đã vô tình định cấu hình sai URL. Trong một số trường hợp, điều này thực sự có thể hoạt động, nhưng nó cũng gây nhầm lẫn.

Vận chuyển này một ứng dụng với App Transport Security bao gồm một số mẹo gỡ lỗi tốt

Thất bại của ATS

Hầu hết các lỗi ATS sẽ xuất hiện dưới dạng CFErrors với mã trong chuỗi -9800. Chúng được định nghĩa trong tiêu đề Security / SecureTransport.h

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

CFNETWORK_DIAGNOSTICS

Đặt biến môi trường CFNETWORK_DIAGNOSTICS thành 1 để có thêm thông tin về bảng điều khiển về sự thất bại

nscurl

Công cụ sẽ chạy qua một số kết hợp ngoại lệ ATS khác nhau, thử kết nối an toàn với máy chủ đã cho theo từng cấu hình ATS và báo cáo kết quả.

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

1
Điểm duy nhất là nscurl chỉ khả dụng trong Mac OS X "El Capitan"
webo80

1
Thêm một mẹo gỡ lỗi, để kiểm tra mật mã kết nối TLS nào đang được máy chủ của bạn sử dụng: curl -v https: // <tên máy chủ>
André Morujão

1
Bất kỳ ý tưởng về những gì có thể gây ra vấn đề nếu cuộn PASS tất cả các bước tốt?
Aston

@ onmyway133 bạn có thể thêm phần giải thích về cách "Đặt biến môi trường CFNETWORK_DIAGNOSTICS thành 1" không?
YakirNa

1
@YakirNa bạn có thể đọc về cách thực hiện điều đó tại đây nshipster.com/launch-argument-and-en môi-biến nó khá đơn giản :)
onmyway133

2

Nếu phụ trợ của bạn sử dụng kiến ​​kết nối an toàn, bạn sẽ sử dụng NSURLSession

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

bạn cần kiểm tra cấu hình máy chủ của mình đặc biệt là để có phiên bản ATS và chứng chỉ SSL Thông tin:

Thay vì chỉ cho phép Kết nối không an toàn bằng cách cài đặt NSExceptionAllowsInsecureHTTPLoads = YES, thay vào đó bạn cần Cho phép bảo mật bị hạ thấp trong trường hợp máy chủ của bạn không đáp ứng yêu cầu tối thiểu (v1.2) cho ATS (hoặc tốt hơn để khắc phục phía máy chủ).

Cho phép bảo mật hạ thấp xuống một máy chủ

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

sử dụng máy khách openssl để điều tra chứng chỉ và nhận cấu hình máy chủ của bạn bằng máy khách openssl:

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

.. tìm ở cuối

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) yêu cầu giao thức TLS (Transport Layer Security) phiên bản 1.2.

Yêu cầu kết nối bằng ATS:

Các yêu cầu đối với kết nối dịch vụ web để sử dụng App Transport Security (ATS) liên quan đến máy chủ, mật mã kết nối và chứng chỉ, như sau:

Chứng chỉ phải được ký bằng một trong các loại khóa sau:

  • Khóa thuật toán băm an toàn 2 (SHA-2) có độ dài tiêu hóa ít nhất 256 (nghĩa là SHA-256 trở lên)

  • Khóa mã hóa Elliptic-Curve (ECC) với kích thước tối thiểu 256 bit

  • Khóa Rivest-Shamir-Adeld (RSA) có độ dài ít nhất 2048 bit Một chứng chỉ không hợp lệ dẫn đến lỗi cứng và không có kết nối.

Các mật mã kết nối sau đây hỗ trợ bảo mật chuyển tiếp (FS) và hoạt động với 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

Cập nhật: hóa ra openssl chỉ cung cấp phiên bản giao thức tối thiểu Giao thức: Liên kết TLSv1


câu hỏi còn lại là có thể diễn giải thông tin openssl để tìm hiểu xem máy chủ có đáp ứng yêu cầu hay không. Ngoài ra Giao thức: TLSv1 có thể là phiên bản makor thay vì 1.x
Idali

Tôi nói chung chung, trong trường hợp sử dụng cổng
Idali

Câu trả lời để lại nhiều câu hỏi mở hơn trả lời. Có vẻ như một vấn đề có thể là ánh xạ giữa các báo cáo openssl và tài liệu của Apple. Từ đầu ra openssl không thể xác định xem TLS 1.2 có được hỗ trợ hay không. Câu trả lời cũng không cho phép xác định xem Bảo mật Chuyển tiếp Hoàn hảo có được hỗ trợ hay không.
zaph

2

Sau hai ngày cố gắng và thất bại, điều làm việc với tôi là mã womble này

với một thay đổi, theo bài đăng này, chúng ta nên ngừng sử dụng các khóa phụ được liên kết với từ điển NSExceptionDomains của loại Công ước đó

  NSTemporaryExceptionMinimumTLSVersion

Và sử dụng tại Công ước mới

  NSExceptionMinimumTLSVersion

thay thế.

tài liệu táo

mã của tôi

<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

Một công cụ hữu ích khác là nmap (brew install nmap)

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

Cung cấp đầu ra

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

rất hữu ích để gỡ lỗi vấn đề chứng chỉ
Lopakhin

0

Lỗi này thỉnh thoảng xuất hiện trong nhật ký khi tôi đang sử dụng phiên bản Cordova iOS bị lỗi / bị lỗi. Nó biến mất khi tôi nâng cấp hoặc hạ cấp cordova iOS.

Máy chủ mà tôi đang kết nối đang sử dụng TLSv1.2 SSL nên tôi biết đó không phải là vấn đề.


0

Trong .plisttệp dự án của bạn thêm quyền này:

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

0

Cú pháp cho cấu hình 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

Câu trả lời cập nhật (sau WWDC 2016):

Các ứng dụng iOS sẽ yêu cầu kết nối HTTPS an toàn vào cuối năm 2016. Việc thử tắt ATS có thể khiến ứng dụng của bạn bị từ chối trong tương lai.

App Transport Security, hay ATS, là một tính năng mà Apple giới thiệu trong iOS 9. Khi ATS được bật, nó buộc một ứng dụng kết nối với các dịch vụ web qua kết nối HTTPS thay vì HTTP không bảo mật.

Tuy nhiên, các nhà phát triển vẫn có thể tắt ATS và cho phép ứng dụng của họ gửi dữ liệu qua kết nối HTTP như được đề cập trong các câu trả lời ở trên. Vào cuối năm 2016, Apple sẽ bắt buộc ATS cho tất cả các nhà phát triển muốn gửi ứng dụng của họ lên App Store. liên kết


0

Thiết bị tôi đã thử nghiệm đã đặt sai thời gian. Vì vậy, khi tôi cố gắng truy cập một trang có chứng chỉ sắp hết, nó sẽ từ chối truy cập vì thiết bị mặc dù chứng chỉ đã hết hạn. Để khắc phục, hãy đặt thời gian thích hợp trên thiết bị!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.