【问题标题】:Custom Certificate in iOS AppiOS 应用中的自定义证书
【发布时间】:2015-03-07 06:42:36
【问题描述】:

我创建了一个证书(p12 类型),并使用 Apple Configurator 安装到 iPad 上。我现在想在我编写的应用程序中访问该证书,但我似乎找不到它的源示例。有很多关于如何使用证书的示例,但我一直无法找到有关如何将其导入应用程序的任何内容。

有人能指出我正确的方向吗?提前致谢。

* 新 *

所以我尝试按照这里的教程https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13 使用清单 2-1 和清单 2-2。现在我放弃了从钥匙串获取证书,而是从主包中加载它。

NSData *certData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"myfile.com" ofType:@"pfx"]];
CFDataRef myCertData = (__bridge_retained CFDataRef)(certData); 

我不确定我的加载是否正确,但是当我调试时 certData 不是 NULL 并且包含字节。

接下来我修改了两个清单中的代码,因为方法签名与 Objective C 方法签名并不真正匹配。有人在这里帮助我,为什么Apple会以这种方式显示它?函数内部没有代码被修改。

- (OSStatus) extractIdentityAndTrust: (CFDataRef) inPKCS12Data withIdentity:(SecIdentityRef *) outIdentity withTrust:(SecTrustRef *) outTrust withPassword:(CFStringRef) keyPassword
{
    OSStatus securityError = errSecSuccess;
    const void *keys[] =   { kSecImportExportPassphrase };
    const void *values[] = { keyPassword };
    CFDictionaryRef optionsDictionary = NULL;

    optionsDictionary = CFDictionaryCreate(NULL, keys, values, (keyPassword ? 1 : 0), NULL, NULL);

    CFArrayRef items = NULL;
    securityError = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);

    if (securityError == 0) {
        CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue (myIdentityAndTrust,
                                             kSecImportItemIdentity);
        CFRetain(tempIdentity);
        *outIdentity = (SecIdentityRef)tempIdentity;
        const void *tempTrust = NULL;
        tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust);

        CFRetain(tempTrust);
        *outTrust = (SecTrustRef)tempTrust;
    }

    if (optionsDictionary)
        CFRelease(optionsDictionary);

    if (items)
        CFRelease(items);

    return securityError;
}

接下来我修改了 copySummaryString 的方法签名。我还必须在函数内部为“身份”变量添加一个尊重。

- (NSString *)copySummaryString:(SecIdentityRef *) identity
{
    // Get the certificate from the identity.
    SecCertificateRef myReturnedCertificate = NULL;
    OSStatus status = SecIdentityCopyCertificate (*identity, &myReturnedCertificate);

    if (status) {
        NSLog(@"SecIdentityCopyCertificate failed.\n");
        return NULL;
    }

    CFStringRef certSummary = SecCertificateCopySubjectSummary
    (myReturnedCertificate);

    NSString* summaryString = [[NSString alloc] initWithString:(__bridge NSString *)certSummary];

    CFRelease(certSummary);

    return summaryString;
}

最后,在我的调用函数中,我创建了一个身份和信任变量并传递:

[self extractIdentityAndTrust:myCertData withIdentity:identity withTrust:trust withPassword:CFSTR("supersecret")];
[self copySummaryString:identity];

当我尝试运行它时,我得到一个 Thread 1: EXC_BAD_ACCESS(code=1, adress=0x2b) 错误并且 XCode 在以下行暂停:

CFStringRef certSummary = SecCertificateCopySubjectSummary

这段代码没有引用我创建的任何变量,所以我真的很惊讶它在这里崩溃了。加载此证书的最终目标是将其用于 HTTPS。我希望我至少在正确的道路上。

【问题讨论】:

    标签: ios objective-c ipad certificate


    【解决方案1】:

    以下是有关通过移动应用查找和使用预安装证书和身份的文档和示例。

    https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-DontLinkElementID_10

    *新

    我检查了您的更新。 这两种方法都很有魅力。

    我使用以下源调用您的方法,并且能够正确提取 SummaryString。

    SecIdentityRef identity = nil;
    SecTrustRef trust = nil;
    
    NSData *certData = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"[Dev] InHouse_Certificates" ofType:@"p12"]];
    CFDataRef myCertData = (__bridge_retained CFDataRef)(certData);
    
    [self extractIdentityAndTrust:myCertData withIdentity:&identity withTrust:&trust withPassword:CFSTR("1234")];
    NSString* summaryString = [self copySummaryString:&identity];
    

    【讨论】:

    • 我遇到了该文档,但无法使其正常工作。我认为我的问题是我不完全了解通过配置器加载证书时存储的位置:我认为它在钥匙串中。当我尝试使用清单 2-5 来查找我的证书时,certificateRef 始终为 null,这对我来说意味着它没有找到它。我用于证书的名称与我的个人资料/主题名称/通用名称下的名称相同。我要么找错地方了,要么我的名字有误。
    • 你的问题现在很清楚了。实际上,您无法检索但可以访问用于在 ios 设备上签署应用程序的证书(mac 不同)。您只能检索捆绑在应用程序中或手动存储在钥匙串中的证书。我希望这能消除您的疑虑。
    • 如果要使用设备上安装的证书,需要联系苹果获取私有API。一些应用程序会这样做。
    • 您好,我不想访问用于签署应用程序的证书。我只想访问我使用 Apple Configurator 上传的证书。
    猜你喜欢
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2019-03-26
    • 2019-07-21
    • 1970-01-01
    • 2011-03-02
    • 2015-05-27
    相关资源
    最近更新 更多