2012-04-16 41 views
0

我建立一个iPhone应用程序,其使用了SSL服务器连接。一切进展顺利。目前,我的服务器证书有问题。目标C核对服务器认证书发行请求

我从这个服务器上下载证书。所以我在我的项目浏览器中有证书。

我试图从服务器的证书与我以前在请求 - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {}

的问题是委托方法下载的,我有完全不知道如何匹配带来的.CER文件中的代码来检查密钥。

回答

0

下面是我用的方法:

NSArray *paths = [[NSBundle mainBundle] pathsForResourcesOfType:@"p12" inDirectory:nil]; 
NSMutableArray *idents = [NSMutableArray array]; 
for (NSString *certPath in paths) { 
    CFDataRef certData = (CFDataRef)[[NSData alloc] initWithContentsOfFile:certPath]; 
    const void *keys[] = {kSecImportExportPassphrase}; 
    const void *values[] = {(CFStringRef)kPassword}; // kPassword should be your password 
    CFDictionaryRef optsDict = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); 

    OSStatus status = -1; 
    CFArrayRef items = NULL; 
    status = SecPKCS12Import(certData, optsDict, &items); 
    if (status == 0) { // noErr or errSecSuccess 
     CFDictionaryRef item = CFArrayGetValueAtIndex(items, 0); 
     SecIdentityRef bundleIdent = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity); 
     [idents addObject:(id)bundleIdent]; 
    } 
    if (optsDict) CFRelease(optsDict); 
    if (items) CFRelease(items); 
    if (certData) CFRelease(certData); 
} 

,瞧 - 你都SecIdentityRefsidents阵列在您的处置。


编辑: 这里的Apple document介绍如何做的正是你想要的。

+0

您好,感谢看起来不错。但我得到一个例外' - [__ NSCFDictionary长]:无法识别的选择发送到实例0x2cab00'在线路设置密码后。 – 2012-04-16 22:39:27

+0

和@all,它根本不能在模拟器中工作。我花了整整一个小时才发现模拟器无法解码。 – 2012-04-16 22:46:37

+0

此代码旨在获得p12证书,并且它可以工作。它失败的原因可能是从错误的文件类型到加密问题。顺便说一句,“模拟器无法解码”是什么意思?作为一个参考,你可以检查https://developer.apple.com/library/mac/#documentation/security/conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html – mit3z 2012-04-17 05:46:35

1

发现这里完美的示例代码:http://www.iphonedevsdk.com/forum/iphone-sdk-development/89542-ssl-connection.html

复制 - 粘贴 - 做,对我的作品。我不知道为什么其他snipplets如此复杂。唯一的问题是本地证书必须在钥匙串中。但我完全看不出这个劣势。也许有人可以告诉我不同​​之处。

// prompted by SSL connection 
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace { 
if([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
{NSLog(@"Attempting SSL Connection..."); 
    return YES; 
} 

NSLog(@"Cannot connect through SSL"); 
return NO;} 
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)theChallenge{ 
challenge = theChallenge; 

// "trust" related authentication challenge, prompted by SSL connection 
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) 
{ 
    //This takes the serverTrust object and checkes it against your keychain 
    SecTrustResultType result; 
    SecTrustEvaluate(challenge.protectionSpace.serverTrust, &result); 

    if (result == kSecTrustResultInvalid) 
     NSLog(@"SSL Challenge Result: Invalid"); 
    else if (result == kSecTrustResultProceed) 
     NSLog(@"SSL Challenge Result: Proceed"); 
    else if (result == kSecTrustResultConfirm) 
     NSLog(@"SSL Challenge Result: Confirm"); 
    else if (result == kSecTrustResultDeny) 
     NSLog(@"SSL Challenge Result: Deny"); 
    else if (result == kSecTrustResultUnspecified) 
     NSLog(@"SSL Challenge Result: Unspecified"); 
    else if (result == kSecTrustResultRecoverableTrustFailure) 
     NSLog(@"SSL Challenge Result: Recoverable Trust Failure"); 
    else if (result == kSecTrustResultFatalTrustFailure) 
     NSLog(@"SSL Challenge Result: Fatal Trust Failure"); 
    else if (result == kSecTrustResultOtherError) 
     NSLog(@"SSL Challenge Result: Other Error"); 

    if(result == kSecTrustResultProceed || result == kSecTrustResultConfirm || result == kSecTrustResultUnspecified) 
    { 
     [challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge]; 
    } 
    else 
    { 
     [self promptForTrust]; 
    } 
}} 
-(void)promptForTrust{//display an error if there are any issues with the connection 
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Cannot Verify Server Identity" message:[NSString stringWithFormat:@"xxxx can't verify the identity of \"%@\". Would you like to continue anyway?", [[Model sharedManager] returnServer]] delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:@"Cancel",@"Details",nil]; 
[alert show]; 
[alert release];}-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{if (buttonIndex == 0) 
{ 
    //May need to add a method to add serverTrust to the keychain like Firefox's "Add Exception" 

    // if the user decides to trust 
    [challenge.sender useCredential:[NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust] forAuthenticationChallenge: challenge]; 
} 
else if (buttonIndex == 1) 
{// if the user decides not to trust 
    [[challenge sender] cancelAuthenticationChallenge:challenge]; 
} 
else if (buttonIndex == 2) 
{ 
    // show details of certificate 

}}