iOS应用程序中的自定义证书(Custom Certificate in iOS App)

470 IT屋

I created a certificate (of p12 type) that I installed onto an iPad using Apple Configurator. I now want to access that certificate in an app I've written but I can't seem to find a source example for it. There are lots of examples on how to use certificates but I've been unable to find anything on how to import it into an app.

Can someone point me in the right direction? Thanks in advance.

* NEW *

So I tried following the tutorial here https://developer.apple.com/library/ios/documentation/Security/Conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html#//apple_ref/doc/uid/TP40001358-CH208-SW13 using Listing 2-1 and Listing 2-2. For now I gave up on getting the certificate from the keychain and instead I load it from the main Bundle.

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

I'm not certain whether my loading is correct but when I debug certData is not NULL and contains bytes.

Next I modified the code in the two listings since the method signatures don't really match an Objective C method signature. Someone help me out here why Apple would show it this way? No code inside the function was modified.

- (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;
}

Next I modified the method signature for copySummaryString. I also had to add a deference inside the function for the 'identity' variable.

- (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;
}

Finally in my calling function I created a identity and trust variable that I pass around:

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

When I try to run this I get a Thread 1: EXC_BAD_ACCESS(code=1, adress=0x2b) error and XCode pauses on the following line:

CFStringRef certSummary = SecCertificateCopySubjectSummary

This code doesn't reference any variable I created so I'm really surprised it's crashing here. The ultimate goal with loading this certificate is to use it for HTTPS. I hope that I'm at least on the right path here.

解决方案

Here is the documentation and example about finding and using of a pre-installed certificate and identity through your mobile app.

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

*NEW

I checked your update. Both you methods works like charm.

I used below source to call your methods, and was able to extract the SummaryString properly.

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];

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



有人可能指向正确的方向吗?提前感谢。



* NEW *



这里 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方法签名。有人帮我在这里为什么苹果会这样显示?



   - (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的方法签名。我还必须在'identity'变量的函数内添加一个引用。



   - (NSString *)copySummaryString:(SecIdentityRef *)identity 
{
//从身份。
SecCertificateRef myReturnedCertificate = NULL;
OSStatus status = SecIdentityCopyCertificate(* identity,& myReturnedCertificate);

if(status){
NSLog(@"SecIdentityCopyCertificate failed.\\\
");
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];


当我尝试运行这个我得到一个线程1:EXC_BAD_ACCESS(code = 1,adress = 0x2b )错误和XCode在以下行中暂停:



  CFStringRef certSummary = SecCertificateCopySubjectSummary 
< / pre>

此代码不引用任何我创建的变量,所以我真的很惊讶,它崩溃了。加载此证书的最终目标是将其用于HTTPS。


解决方案

这里是关于查找和使用的文档和示例通过您的移动应用预安装的证书和身份。



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



*新 / p>

我检查了您的更新。
两种方法都像charm一样工作。



我在下面用来调用你的方法,并且能够正确提取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];

本文地址:IT屋 » iOS应用程序中的自定义证书