iOS HTTPS请求101

NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813) 

非常非常令人沮丧! 我已经用这个拉了几个小时的头发。 我在我的Linode服务器上使用自签名证书。 港口是8000,不能让它在443上工作。我不认为这是理由。 这是我的代码,它是99%的样板:

 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.myserver.com:8000/test.json"]]; NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; 

在底部:

 #pragma mark NSURLConnectionDelegate - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { NSLog(@"protectionSpace: %@", [protectionSpace authenticationMethod]); // We only know how to handle NTLM authentication. if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodNTLM]) return YES; // Explicitly reject ServerTrust. This is occasionally sent by IIS. if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) return NO; return NO; } - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSLog(@"%@", response); } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { NSLog(@"%@", data); } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"didFailWithError"); NSLog([NSString stringWithFormat:@"Connection failed: %@", [error description]]); } 

OMG帮助!

UPDATE

它使用这个委托方法。 我收到了答复,但是有一个问题。

 - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { [[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"user" password:@"password" persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge]; } 

我提供的“用户”和“密码”是完全随机的,不会被服务器检查。 在接受我的服务器上的连接之前,如何validation凭证?

编辑:我正在运行一个Node.js服务器

获取相应的错误描述可能有所帮助:

所以,首先错误域kCFStreamErrorDomainSSL意味着错误代码是Security / SecureTransport.h中定义的SSL错误代码:

kCFStreamErrorDomainSSL,-9813表示:

errSSLNoRootCert = -9813, /* cert chain not verified by root */

这就是说,您没有受信任的根证书,并且由于该validation失败而导致连接失败。

在设备上提供一个用于服务器信任authentication的根证书,你很好。

有几种方法可以使用自签名证书来实现服务器信任authentication,这是一种比另一种更安全的方法。

最简单的方法需要存储在应用程序包中的自签名证书,然后进行检索并进行字节比较。 这里是一个例子:

使用自签名证书实施服务器信任authentication 。

这些是必须阅读: 技术说明TN2232 HTTPS服务器信任评估和技术问答QA1360描述kSecTrustResultUnspecified错误 。

更优选的方法是使用您可以自己的CA(证书颁发机构)。 也就是说,您创build了自己的CA,并使用此CA签署了证书。

步骤是类似的:

  1. 在您的应用程序中联合您的CA根证书的DER文件。
  2. 处理服务器信任authentication如下:

    1. 获得authentication挑战
    2. 从挑战中检索信任对象
    3. 从您的包中的数据创build一个证书对象
    4. 使用函数SecTrustSetAnchorCertificates将证书对象设置为信任对象的SecTrustSetAnchorCertificates
    5. 评估信任

不知道这是否真的能解决问题,但可能有帮助。 你应该使用

 – connection:willSendRequestForAuthenticationChallenge: 

因为其他方法已被弃用。 看看NSURLConnectionDelegate协议的概述