繁体   English   中英

iOS HTTPS请求101

[英]iOS HTTPS requests 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]]);
}

天啊帮忙!

UPDATE

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

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

}

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

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

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

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

kCFStreamErrorDomainSSL,-9813表示:

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

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

在设备上提供服务器信任身份验证的根证书,你没事。

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

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

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

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

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

步骤类似:

  1. Bundel您的应用程序中CA的根证书的DER文件。
  2. 处理服务器信任身份验证,如下所示:

    1. 获得身份验证挑战
    2. 从挑战中检索信任对象
    3. 从捆绑中的数据创建证书对象
    4. 使用函数SecTrustSetAnchorCertificates将证书对象设置为信任对象的SecTrustSetAnchorCertificates
    5. 评估信任

不确定这是否能真正解决问题,但它可能有所帮助。 你应该使用

– connection:willSendRequestForAuthenticationChallenge:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM