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

コピー - 貼り付け - 完了、私にとってはうまくいきます。なぜ他のスニプレットが複雑なのか、私にはわかりません。唯一のことは、ローカル証明書がキ​​ーチェーンにある必要があるということです。でもデメリットが全く見えない。多分誰かが私に違いを教えてくれるでしょう。

// 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);
}

出来上がり - すべてを自由SecIdentityRefsに配置できます。idents


編集:これは、あなたが望むことを正確に行う方法を説明するAppleドキュメントです。

于 2012-04-16T19:07:52.953 に答える