2012-04-16 37 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 

}}