【问题标题】:iPhone: HTTPS client cert authenticationiPhone:HTTPS 客户端证书认证
【发布时间】:2010-11-30 10:40:00
【问题描述】:

我正在与客户端证书身份验证作斗争。当服务器需要一个凭证(在这种情况下是一个证书)时,这个方法会从 NSURLConnection 委托中调用:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

我想从文件中加载证书,填写凭据并运行此方法:

[[challenge sender] useCredential:[self credential] forAuthenticationChallenge:challenge];

但我不知道如何初始化(或填充)SecIdentityRef 参数。这是我创建凭据的代码:

NSString *certPath = [[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"cer"];
NSData *certData = [[NSData alloc] initWithContentsOfFile:certPath];

SecIdentityRef myIdentity;  // ???

SecCertificateRef myCert = SecCertificateCreateWithData(NULL, (CFDataRef)certData);
[certData release];
SecCertificateRef certArray[1] = { myCert };
CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
CFRelease(myCert);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity
                                  certificates:(NSArray *)myCerts
                                   persistence:NSURLCredentialPersistencePermanent];
CFRelease(myCerts);

有人知道怎么解决吗?谢谢。


我终于找到了解决办法,但是又出现了一个新问题:

我的客户端没有将证书发送到服务器。服务器请求证书后,应用程序运行此方法:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

我填写了凭据(就像我上面提到的那样),但连接以错误结束:NSURLErrorDomain -1206。根据服务器日志,客户端证书不是由应用程序发送的。

有人遇到过这种行为吗?我是否需要以某种方式验证应用程序中的证书?或者还有什么可以让它工作的?如果有帮助,我可以提供我当前的代码。感谢您的任何想法...

【问题讨论】:

    标签: iphone authentication ssl certificate


    【解决方案1】:

    如果您在钥匙串中存储此信息,您还可以在钥匙串中搜索身份:

    + (SecIdentityRef)dumpSecIdentityRef
    {
    OSStatus    err;
    CFArrayRef  result;
    CFIndex     resultCount;
    CFIndex     resultIndex;
    
    result = NULL;
    err = SecItemCopyMatching((__bridge CFDictionaryRef) [NSDictionary dictionaryWithObjectsAndKeys:
                                                          (__bridge id)kSecClassIdentity,
                                                          kSecClass, kSecMatchLimitAll,
                                                          kSecMatchLimit, kCFBooleanTrue,
                                                          kSecReturnRef, kCFBooleanTrue,
                                                          kSecReturnAttributes, nil],
                              (CFTypeRef *) &result);
    
    if ((result != NULL) && (err == noErr)) {
    
        NSMutableArray *identitiesArray = [NSMutableArray new];
    
        resultCount = CFArrayGetCount(result);
        for (resultIndex = 0; resultIndex < resultCount; resultIndex++) {
            NSDictionary *  thisResult;
            thisResult = (__bridge NSDictionary *) CFArrayGetValueAtIndex(result, resultIndex);
            NSLog(@"%@", (__bridge id)(result));
            [identitiesArray addObject:thisResult];
        }
    
        CFRelease(result);
        //TO DO - choose correct identity object from array.
        SecIdentityRef myIdentity = (__bridge SecIdentityRef)([[identitiesArray objectAtIndex:0] valueForKey:@"v_Ref"]);
    
        return myIdentity;
    }
    return nil;
    }
    

    【讨论】:

      【解决方案2】:

      我使用这些步骤:

      1. 使用 SecPKCS12Import 函数从 pkcs12 证书文件中提取 SecIdentityRef
      2. 使用SecIdentityCopyCertificate函数获取SecCertificateRef

      其余的(凭据初始化)与我的问题相同...如果您愿意,我可以在此处放置更多代码。请注意,iphone模拟器中存在一个错误(http://openradar.appspot.com/7090030),因此无法在模拟器中使用大量证书。

      【讨论】:

        【解决方案3】:

        当然问题出在 xcode 中的 iPhone 模拟器上 :) 更新到 3.1 版后它开始工作...

        【讨论】:

        • 只是让您的问题更具可读性的提示:不要将问题发布为新答案。它往往使线程更难阅读。请记住,您的问题可能对其他人有用,并且让他们能够看到您的过程和最终答案很重要。谢谢!
        猜你喜欢
        • 2015-09-06
        • 2012-09-04
        • 2013-08-04
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-09
        相关资源
        最近更新 更多