2011-12-01 153 views
3

我正在写一个应用程序与需要客户端使用客户端证书进行身份验证的服务器进行通信。我需要从应用程序包中的.p12文件中提取证书并将其添加到应用程序钥匙串中。将客户端证书导入到iPhone的钥匙串

我一直在试图弄清楚如何从苹果的"Certificate, Key, and Trust Services Tasks for iOS"工作,但对我来说,它似乎不完整,并没有指定我如何添加任何东西到钥匙串(?)。

我很失落,任何帮助appriciated,在此先感谢!

回答

4

Certificate, Key, and Trust Services Tasks for iOS”包含的信息足以从.p12文件中提取证书。

  • 从列表2-1演示了如何从上市2-2二线提取SecIdentityRef

  • (// 1)展示了如何复制 SecCertificateRef出SecIdentityRef的。

例如加载P12文件,提取证书,安装到钥匙串。 (不包括错误处理和内存管理)

NSString * password = @"Your-P12-File-Password"; 
    NSString * path = [[NSBundle mainBundle] 
        pathForResource:@"Your-P12-File" ofType:@"p12"]; 

    // prepare password 
    CFStringRef cfPassword = CFStringCreateWithCString(NULL, 
                password.UTF8String, 
                kCFStringEncodingUTF8); 
    const void *keys[] = { kSecImportExportPassphrase }; 
    const void *values[] = { cfPassword }; 
    CFDictionaryRef optionsDictionary 
    = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, 
                NULL, NULL); 

    // prepare p12 file content 
    NSData * fileContent = [[NSData alloc] initWithContentsOfFile:path]; 
    CFDataRef cfDataOfFileContent = (__bridge CFDataRef)fileContent; 

    // extract p12 file content into items (array) 
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    OSStatus status = errSecSuccess; 
    status = SecPKCS12Import(cfDataOfFileContent, 
          optionsDictionary, 
          &items); 
    // TODO: error handling on status 

    // extract identity 
    CFDictionaryRef yourIdentityAndTrust = CFArrayGetValueAtIndex(items, 0); 
    const void *tempIdentity = NULL; 
    tempIdentity = CFDictionaryGetValue(yourIdentityAndTrust, 
             kSecImportItemIdentity); 

    SecIdentityRef yourIdentity = (SecIdentityRef)tempIdentity; 


    // get certificate from identity 
    SecCertificateRef yourCertificate = NULL; 
    status = SecIdentityCopyCertificate(yourIdentity, &yourCertificate); 


    // at last, install certificate into keychain 
    const void *keys2[] = { kSecValueRef,    kSecClass }; 
    const void *values2[] = { yourCertificate, kSecClassCertificate }; 
    CFDictionaryRef dict 
    = CFDictionaryCreate(kCFAllocatorDefault, keys2, values2, 
              2, NULL, NULL); 
    status = SecItemAdd(dict, NULL); 

    // TODO: error handling on status