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

查看:15
本文介绍了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]]);
}

天哪!帮助!

更新

它与这个委托方法一起工作.我正在收到回复,但出现问题.

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:

所以,首先错误域 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:

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

这些也是必读的:技术说明 TN2232HTTPS 服务器信任评估技术问答 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. 在您的应用中捆绑 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天全站免登陆