iPhone:HTTPS客户端证书身份验证

iPhone:HTTPS客户端证书身份验证,iphone,authentication,ssl,certificate,Iphone,Authentication,Ssl,Certificate,我正在与客户端证书身份验证进行斗争。当服务器需要凭据(本例中为证书)时,将从NSURLConnection委托调用此方法: - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge 我想从文件加载证书,填写凭证并运行此方法: [[challenge sender] useCredential:[self

我正在与客户端证书身份验证进行斗争。当服务器需要凭据(本例中为证书)时,将从NSURLConnection委托调用此方法:

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
我想从文件加载证书,填写凭证并运行此方法:

[[challenge sender] useCredential:[self credential] forAuthenticationChallenge:challenge];
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)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);
有人知道怎么解决吗?谢谢


我终于找到了解决方案,但这里出现了一个新问题:

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

[[challenge sender] useCredential:[self credential] forAuthenticationChallenge:challenge];
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
我填写了凭证(就像上面提到的),但是连接以一个错误结束:NSURLErrorDomain-1206。根据服务器日志,客户端证书不是由应用程序发送的


有人有过这种行为吗?我是否需要以某种方式验证应用程序中的证书?或者其他什么能让它工作?如果有帮助,我可以提供我当前的代码。谢谢你的建议…

当然问题出在xcode中的iPhone模拟器:)升级到3.1版后,它开始工作…

我使用以下步骤:

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

  • 其余的(凭证初始化)与我的问题相同。。。如果你愿意,我可以在这里添加更多代码。请注意,iphone模拟器中有一个bug(),因此不可能在模拟器中使用大量证书。

    如果您将此信息存储在keychain中,也可以在keychain中搜索身份:

    + (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;
    }
    
    +(SecIdentityRef)dumpSecIdentityRef
    {
    骨性关节炎;
    CFArrayRef结果;
    cfindexresultcount;
    CFIndex结果指数;
    结果=空;
    err=SecItemCopyMatching((_桥CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys:
    (_桥id)kSecClassIdentity,
    kSecClass,kSecMatchLimitAll,
    kSecMatchLimit,kCFBooleanTrue,
    kSecReturnRef,kCFBooleanTrue,
    kSecReturnAttributes,nil],
    (CFTypeRef*)和结果);
    if((result!=NULL)&&(err==noErr)){
    NSMUTABLEARRY*标识数组=[NSMUTABLEARRY new];
    结果计数=CFArrayGetCount(结果);
    对于(resultIndex=0;resultIndex
    让您的问题更具可读性的提示:不要将问题作为新答案发布。它往往使线程更难阅读。记住,你的问题可能对其他人有用,让他们能够看到你的过程和最终答案是很重要的。谢谢