我正在使用NSULConnection通过SSL将数据发送到Web服务。服务器使用通配符证书(* .mydomain.com)进行签名。证书使用RES SHA256和TLS 1.2,并由CA签名。我正在尝试使用以下代码发送数据:
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init];
[req setTimeoutInterval:60];
[req setHTTPMethod:@"POST"];
// ... Set content type and add data to body ... //
[req setURL:@"https://subdomain.mydomain.com/service/"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSLog(@"Starting Upload");
NSURLSessionDataTask *task = [session dataTaskWithRequest:req
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
// .. Handle Completion .. //
}];
[task resume];
当我运行上面的代码时,我得到以下输出。
CFNetwork SSLHandshake failed (-9801) NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)
所以,我尝试添加此帖中解释的例外:CFNetwork SSLHandshake failed iOS 9
但是没有运气来解决错误。然后我切换到使用http
而不是https
,同时留下上面解释的配置更改,它确实有效。然而,这远非理想的解决方案。 http
适用于测试,但此应用将处理需要SSL的数据。如何让SSL工作?
修改
以下是在我的服务网址的nscurl --ats-diagnostics
版本上运行https
的结果
================================================================================ Default ATS Secure Connection --- ATS Default Connection Result : PASS --- ================================================================================ Allowing Arbitrary Loads --- Allow All Loads Result : PASS --- ================================================================================ Configuring TLS exceptions for **** --- TLSv1.2 Result : PASS --- --- TLSv1.1 Result : PASS --- --- TLSv1.0 Result : PASS --- ================================================================================ Configuring PFS exceptions for **** --- Disabling Perfect Forward Secrecy Result : PASS --- ================================================================================ Configuring PFS exceptions and allowing insecure HTTP for **** --- Disabling Perfect Forward Secrecy and Allowing Insecure HTTP Result : PASS --- ================================================================================ Configuring TLS exceptions with PFS disabled for **** --- TLSv1.2 with PFS disabled Result : PASS --- --- TLSv1.1 with PFS disabled Result : PASS --- --- TLSv1.0 with PFS disabled Result : PASS --- ================================================================================ Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for **** --- TLSv1.2 with PFS disabled and insecure HTTP allowed Result : PASS --- --- TLSv1.1 with PFS disabled and insecure HTTP allowed Result : PASS --- --- TLSv1.0 with PFS disabled and insecure HTTP allowed Result : PASS --- ================================================================================
修改2
以下是我添加的例外情况:
<dict>
<key>mydomain.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>1.0</string>
<key>NSTemporaryExceptionRequiresForwardSecrecy</key>
<false/>
</dict>
</dict>
curl -v
* CAfile: /opt/local/share/curl/curl-ca-bundle.crt CApath: none * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server key exchange (12): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384 * Server certificate: * subject: C=XXX; ST=XXX; L=XXX; O=XXX; CN=*.mydomain.com * start date: 2015-08-17 00:00:00 GMT * expire date: 2018-11-14 12:00:00 GMT * subjectAltName: subdomain.mydomain.com matched * issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA * SSL certificate verify ok.
openssl s_client -connect
CONNECTED(00000003) depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=XXX/ST=XXX/L=XXX/O=XXX/CN=*.mydomain.com i:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA 1 s:/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA --- Server certificate -----BEGIN CERTIFICATE----- . . . -----END CERTIFICATE----- subject=/C=XXX/ST=XXX/L=XXX/O=XXX/CN=*.mydomain.com issuer=/C=US/O=DigiCert Inc/CN=DigiCert SHA2 Secure Server CA --- No client certificate CA names sent --- SSL handshake has read 3033 bytes and written 490 bytes --- New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : ECDHE-RSA-AES256-SHA384 Session-ID: XXX Session-ID-ctx: Master-Key: XXX Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1454971371 Timeout : 300 (sec) Verify return code: 20 (unable to get local issuer certificate) ---