ios - NSUrlConnection sendAsynchronousRequest 和自签名证书

标签 ios ios5 nsurlconnection

我正在编写一些执行 http 请求的 API 代码,并且我一直在使用 [NSUrlConnection:sendAsynchronousRequest:queue:completionHandler] 进行调用,因为它使得编写简单的处理程序变得非常容易,而且我不必为每个调用设置不同的类和不同的委托(delegate)。

我遇到的问题是,接受自签名证书的唯一方法似乎是让一个实现几个函数的委托(delegate)说证书没问题。有没有办法用使用 block 的异步方法来做到这一点?

最佳答案

不,但是委托(delegate)调用并没有那么难。这是您需要的代码:

1) 将其设为静态文件

static CFArrayRef certs;

2) 在初始化时执行此操作:

    // I had a crt certificate, needed a der one, so found this site:
    // http://fixunix.com/openssl/537621-re-der-crt-file-conversion.html
    // and did this from Terminal: openssl x509 -in crt.crt -outform der -out crt.der
    NSString *path = [[NSBundle mainBundle] pathForResource:@"<your name>" ofType:@"der"];
    assert(path);
    NSData *data = [NSData dataWithContentsOfFile:path];
    assert(data);

    SecCertificateRef rootcert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)data);
    if(rootcert) {
        const void *array[1] = { rootcert };
        certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks);
        CFRelease(rootcert);    // for completeness, really does not matter 
    } else {
        NSLog(@"BIG TROUBLE - ROOT CERTIFICATE FAILED!");
    }

3) 然后添加这个方法:

- (void)connection:(NSURLConnection *)conn didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
#pragma unused(conn)
    // NSLog(@"didReceiveAuthenticationChallenge %@ FAILURES=%zd", [[challenge protectionSpace] authenticationMethod], (ssize_t)[challenge previousFailureCount]);

    /* Setup */
    NSURLProtectionSpace *protectionSpace   = [challenge protectionSpace];
    assert(protectionSpace);
    SecTrustRef trust                       = [protectionSpace serverTrust];
    assert(trust);
    CFRetain(trust);                        // Don't know when ARC might release protectionSpace
    NSURLCredential *credential             = [NSURLCredential credentialForTrust:trust];

    BOOL trusted = NO;
    OSStatus err;
    SecTrustResultType trustResult = 0;

    err = SecTrustSetAnchorCertificates(trust, certs);
    if (err == noErr) {
        err = SecTrustEvaluate(trust, &trustResult);
        if(err == noErr) {
        // http://developer.apple.com/library/mac/#qa/qa1360/_index.html
            switch(trustResult) {
            case kSecTrustResultProceed:
            case kSecTrustResultConfirm:
            case kSecTrustResultUnspecified:
                trusted = YES;
                break;
            }       
        }
    }
    CFRelease(trust);

    // Return based on whether we decided to trust or not
    if (trusted) {
        [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
    } else {
        NSLog(@"Trust evaluation failed");
        [[challenge sender] cancelAuthenticationChallenge:challenge];
    }
}

关于ios - NSUrlConnection sendAsynchronousRequest 和自签名证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11615237/

相关文章:

ios - 在应用内购买 开发者需要采取行动 状态

iphone - 使用 CGContextRef 绘图

ios - 基本身份验证 iOS 6 - 不工作

ios - 实现 NSURLConnection 委托(delegate)

ios - 使用苹果在权限消息中缺少应用名称登录

ios - 带有 UITableView 的 UIPageViewController,滑动以删除单元格?

ios - 如何在应用程序关闭时删除图像缓存?

iphone - 用于测试的设备和 iOS 版本的最佳实践。同一台设备需要多个 iOS 版本?

ios - 从服务器下载数据并在 UITableViewController 或 UIViewController 中显示而不会卡住其 GUI 的最佳方法是什么?

ios - 关闭模态视图时不调用 ViewDidAppear