CFNetwork SSLHandshake가 iOS 9에 실패했습니다.


Answers

** iOS 10 베타에 대한 중요 참고 사항 : **

iOS 10에서 TLS 문자열은 "TLSv1.0"형식이어야합니다. "1.0"일 수는 없습니다. 예, 이것은 어리 석고 app-breaking입니다. iOS 개발에 오신 것을 환영합니다.

위의 조언의 다음 조합이 작동합니다.

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

iOS 9 베타 1 사용자에게는이 문제가 있습니까?

나는 webservice에 연결하기 위해 표준 NSURLConnection을 사용하고 webservice에 대한 호출이 이루어 지 자마자 아래 오류가 발생합니다. 현재 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];



업데이트 된 답변 (WWDC 2016 이후) :

iOS 앱에는 2016 년 말까지 보안 HTTPS 연결이 필요합니다. ATS를 사용 중지하면 향후 앱이 거부 될 수 있습니다.

App Transport Security (ATS)는 Apple에서 iOS 9에 도입 한 기능입니다. ATS를 사용하면 앱이 보안되지 않은 HTTP 대신 HTTPS 연결을 통해 웹 서비스에 연결됩니다.

그러나 개발자는 여전히 위의 답변에서 언급 한 것처럼 ATS를 해제하고 앱이 HTTP 연결을 통해 데이터를 보낼 수 있도록 허용 할 수 있습니다. 2016 년 말에 애플은 앱 스토어에 앱을 제출하기를 희망하는 모든 개발자에게 ATS를 의무화 할 예정이다. 링크




또 다른 유용한 도구는 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



테스트 한 기기에 잘못된 시간이 설정되었습니다. 그래서 곧 인증서가 만료 된 페이지에 액세스하려고 시도했을 때 인증서가 만료되었지만 액세스가 거부되었으므로 액세스가 거부되었습니다. 문제를 해결하려면 기기에서 적절한 시간을 설정하십시오!




NSURLSession을 사용하여 백엔드에서 보안 연결을 사용하는 경우

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

특히 ATS 버전 및 SSL 인증서를 얻으려면 서버 구성을 점검해야합니다. 정보 :

NSExceptionAllowsInsecureHTTPLoads = YES 로 설정하여 안전하지 않은 연결허용하는 대신 서버가 ATS에 대해 최소 요구 사항 (v1.2)을 충족하지 못하거나 서버 측을 수정하는 데 더 적합하지 않은 경우 NSExceptionAllowsInsecureHTTPLoads = YES 보안 허용 이 필요합니다.

단일 서버에 대한 보안 저하 허용

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

ATS (응용 프로그램 전송 보안)에는 TLS (전송 계층 보안) 프로토콜 버전 1.2가 필요합니다.

ATS를 사용하여 연결하기위한 요구 사항 :

ATS (App Transport Security)를 사용하기위한 웹 서비스 연결의 요구 사항은 다음과 같이 서버, 연결 암호 및 인증서가 필요합니다.

인증서는 다음 유형의 키 중 하나를 사용하여 서명해야합니다.

  • 다이제스트 길이가 256 이상인 SHA-2 (Secure Hash Algorithm 2) 키 (즉, SHA-256 이상)
  • 최소 256 비트 크기의 Elliptic-Curve Cryptography (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 링크




프로젝트에서 .plist 파일에 다음 권한 추가 :

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