0

我构建了一个使用 ssl 服务器连接的 iPhone 应用程序。到目前为止一切进展顺利。目前我对服务器证书有一个小问题。

我从该服务器下载了证书。所以我的项目浏览器中有证书。

我正在尝试将来自服务器的证书与我之前在请求的委托方法中下载的证书进行匹配 - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {}

问题是,我完全不知道如何在代码中引入 .cer 文件来检查密钥。

4

2 回答 2

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

}}
于 2012-05-22T22:48:31.000 回答
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 文档,它描述了如何做你想做的事。

于 2012-04-16T19:07:52.953 回答