首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSURLCredential在没有任何信息的情况下崩溃-基于证书的身份验证

NSURLCredential在没有任何信息的情况下崩溃-基于证书的身份验证
EN

Stack Overflow用户
提问于 2013-06-14 12:06:14
回答 2查看 645关注 0票数 0

在我的应用中,我需要根据证书对用户进行身份验证。我是这样做的1.首先,我将证书导出到沙箱中。2.然后从证书中提取SecIdentityRef,将其添加到密钥链,然后从沙箱中删除证书。3.当我将这个身份传递给NSURL连接的身份验证挑战时,应用程序崩溃了,没有提供任何有意义的信息。

下面是所有相关的代码片段

代码语言:javascript
复制
//Exporting the certificate into the app and extracting the identity from it

- (void)importCertificateIntoKeychain:(NSString *)Password
{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"Certificates"];
    NSString *certFolderName = [[[[NSUserDefaults standardUserDefaults] objectForKey:@"CertificatePath"] lastPathComponent]stringByDeletingPathExtension];
    NSString *path = [NSString stringWithFormat:@"%@/%@",dataPath,certFolderName];
    NSArray*array = [[NSFileManager defaultManager]
                     contentsOfDirectoryAtPath:
                     path
                     error:nil];
    NSString *thePath;
    NSString *fileName;
    for (int i=0;i<array.count;i++) {
        if ([[array objectAtIndex:i]hasSuffix:@".pfx"]) {
            fileName= [array objectAtIndex:i];
            thePath = [NSString stringWithFormat:@"%@/%@",path,fileName];
        }
    }

    SecIdentityRef identityApp = nil;

    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
    NSString *pwd = Password;
    CFStringRef password = (CFStringRef)CFBridgingRetain(pwd);
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
    CFRelease(options);
    CFRelease(password);
    if (securityError == errSecSuccess) {
        NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items));
        CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
        identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
        SecCertificateRef certificate = NULL;
        SecIdentityCopyCertificate (identityApp, &certificate);

       OSStatus status = errSecSuccess;

        CFTypeRef persistent_ref = NULL;
        const void *keys[] = { kSecReturnPersistentRef, kSecValueRef };
        const void *values[] = { kCFBooleanTrue, identityApp };
        CFDictionaryRef dict = CFDictionaryCreate(NULL, keys, values,
                                                             2, NULL, NULL);
        status = SecItemAdd(dict, &persistent_ref);
        NSLog(@"Status %ld",status);

        if (dict)
        CFRelease(dict);
        [Utils deleteCertificateFromInboxFolder];
    } else {
        NSLog(@"Error opening Certificate.");
        [Utils displayAlertWithTitle:@"Wrong Password" andMessage:@"Error opening certificate"];
    }
}

在身份验证质询中传递此凭据

代码语言:javascript
复制
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate)
    {
        fprintf(stderr, "identities:\n");
        fprintf(stderr, "certificates:\n");
        NSLog(@"NSURLAuthenticationMethodClientCertificate");

        SecIdentityRef identity;
        identity = (__bridge SecIdentityRef)([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]);
        SecCertificateRef certificate1 = NULL;
        OSStatus *stat = SecIdentityCopyCertificate (identity, &certificate1);
        //const void *certs[] = {certificate1};

        SecCertificateRef certArray[1] = { certificate1 };
        CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
        CFRelease(certificate1);
        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity
                                                                 certificates:(__bridge NSArray *)myCerts
                                                                  persistence:NSURLCredentialPersistencePermanent];
        CFRelease(myCerts);

//        CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);
//        
//        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistenceNone];
        [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}

一旦我将此凭据传递给NSURLChallenge发件人,应用程序就会崩溃。

非常感谢您的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-14 13:16:38

好了,我好像修好了。

变化

代码语言:javascript
复制
 identity = (__bridge SecIdentityRef)([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]);

identity = (SecIdentityRef)CFBridgingRetain([self _dumpCredentialsOfSecClass:kSecClassIdentity printSelector:@selector(_printIdentity:attributes:)]);

希望这对某些人有帮助

票数 0
EN

Stack Overflow用户

发布于 2013-06-14 12:45:17

你有没有试着为你的项目启用僵尸对象?它可能会帮助你找出哪里出了问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17100917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档