iOS HTTPS请求101 [英] iOS HTTPS requests 101

查看:191
本文介绍了iOS HTTPS请求101的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

非常非常令人沮丧!我一直在用头发拉几个小时。我在Linode服务器上使用自签名证书。端口是8000,无法在443上工作。我不相信这是原因。这是我的代码,它是99%样板:

Very, very frustrating! I've been pulling my hair for hours with this. I'm using a self-signed certificate on my Linode server. The port is 8000, couldn't get it to work on 443. I don't believe this is the reason though. Here's my code, it's 99% boilerplate:

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

UPDATE

它适用于此委托方法。我收到了回复,但是有问题。

It worked with this delegate method. I'm receiving the response, but there is a problem.

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

}

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

The "user" and "password" that I have provided are completely random and aren't checked by the server. How can I verify the credentials before accepting the connection on my server?

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

I'm running a Node.js server

推荐答案

获取相应的错误说明可能有所帮助:

Getting the corresponding error description may help:

所以,首先是错误domain kCFStreamErrorDomainSSL 表示错误代码是Security / SecureTransport.h中定义的SSL错误代码:

So, first the error domain kCFStreamErrorDomainSSL means that the error code is an SSL error code as defined in Security/SecureTransport.h:

kCFStreamErrorDomainSSL ,-9813表示:

kCFStreamErrorDomainSSL, -9813 means:

errSSLNoRootCert = -9813,/ *证书链未经root *验证* /

这只是意味着,您没有受信任的根证书,并且由于该身份验证失败,连接失败。

And that simply means, you have no trusted root certificate and the connection fails because of that authentication failure.

提供设备上用于服务器信任身份验证的根证书,你很好。

Provide a root certificate on the device for the server trust authentication and you are fine.

有几种方法可以实现服务器信任身份验证签名证书,比另一个更安全。

There are a few approaches to implement server trust authentication with self-signed certificates, the one more secure than the other.

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

The simplest approach requires a self-signed certificate which is stored in the bundle of the app, then retrieved and simply byte-compared. Here is an example:

使用自签名证书实施服务器信任身份验证

这些必须阅读:技术说明TN2232
HTTPS服务器信任评估
技术Q& A QA1360描述kSecTrustResultUnspecified错误

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

The more preferred approach is to use a CA (Certificate Authority) which you can be yourself. That is, you create your own CA and your certificates signed with this CA.

步骤类似:


  1. Bundel您应用程序中CA根证书的DER文件。

  2. 按如下方式处理服务器信任身份验证:

  1. Bundel the DER file of your CA's root certificate in your app.
  2. Handle the server trust authentication as follows:


  1. 获取身份验证质询

  2. 从质询中检索信任对象

  3. 创建一个来自数据包中数据的证书对象

  4. 使用函数 SecTrustSetAnchorCertificates 将证书对象设置为信任对象的锚点。

  5. 评估信托

  1. get the authentication challenge
  2. retrieve the trust object from the challenge
  3. create a certificate object from the data in your bundle
  4. set the certificate object as an anchor to the trust object using function SecTrustSetAnchorCertificates.
  5. evaluate the trust


这篇关于iOS HTTPS请求101的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆