6

チームiPhoneでクライアント証明書を使用した認証ができません

2ウェイSSLで設定された.netベースのRESTサービスがあります。私のiPhone側では、デバイスプロファイルにサーバー証明書をインストールし、クライアント証明書はアプリケーションリソースとしてバンドルされています。サーバー証明書の検証は正常ですが、クライアント証明書の認証は失敗します。以下は私のコードスニペットです

- (void)connection:(NSURLConnection *) connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    NSLog(@"Authentication challenge with host: %@", challenge.protectionSpace.host); 

    if([challenge previousFailureCount] == 0) { 
     NSURLProtectionSpace *protectionSpace = [challenge protectionSpace]; 
     NSString *authMethod = [protectionSpace authenticationMethod]; 
     if(authMethod == NSURLAuthenticationMethodServerTrust) { 
      NSLog(@"Verifying The Trust"); 
      [[challenge sender] useCredential:[NSURLCredential credentialForTrust:[protectionSpace serverTrust]] forAuthenticationChallenge:challenge]; 
     } 
     else if(authMethod == NSURLAuthenticationMethodClientCertificate) { 
      NSLog(@"Trying Certificate"); 
      // load cert 

      NSString *thePath = [[NSBundle mainBundle] 
           pathForResource:@"Myclientcertificate" ofType:@"pfx"]; 
      NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath]; 
      CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;    

      OSStatus status = noErr; 
      SecIdentityRef myIdentity; 
      SecTrustRef myTrust; 

      status = extractIdentityAndTrust(
              inPKCS12Data, 
              &myIdentity, 
              &myTrust); 

      SecTrustResultType trustResult; 

      if (status == noErr) {          
       status = SecTrustEvaluate(myTrust, &trustResult); 
      } 

      SecCertificateRef myCertificate; 
      SecIdentityCopyCertificate(myIdentity, &myCertificate); 
      const void *certs[] = { myCertificate }; 
      CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL); 


      NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent]; 

      [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; 


     } 
    } 

} 

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{ 
    BOOL result; 
    NSLog(@"canAuthenticateAgainstProtectionSpace: %@", protectionSpace.authenticationMethod); 
    if ([protectionSpace authenticationMethod] == NSURLAuthenticationMethodServerTrust) { 
     result= YES; 
    } else if([protectionSpace authenticationMethod] == NSURLAuthenticationMethodClientCertificate) { 
     result = YES; 
    } 
    return result; 
} 

OSStatus extractIdentityAndTrust(CFDataRef inPKCS12Data, SecIdentityRef *identity, SecTrustRef *trust){ 
    OSStatus securityError = errSecSuccess; 


    CFStringRef password = CFSTR("1234"); 
    const void *keys[] = { kSecImportExportPassphrase }; 
    const void *values[] = { password }; 
    CFDictionaryRef optionsDictionary = CFDictionaryCreate(
                  NULL, keys, 
                  values, 1, 
                  NULL, NULL); 
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    securityError = SecPKCS12Import(inPKCS12Data, 
            optionsDictionary, 
            &items); 

     if (securityError == 0) {         
     CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex (items, 0); 
     const void *tempIdentity = NULL; 
     tempIdentity = CFDictionaryGetValue (myIdentityAndTrust, 
              kSecImportItemIdentity); 
     *identity = (SecIdentityRef)tempIdentity; 
     const void *tempTrust = NULL; 
     tempTrust = CFDictionaryGetValue (myIdentityAndTrust, kSecImportItemTrust); 
     *trust = (SecTrustRef)tempTrust; 
    } 

    if (optionsDictionary) { 
     CFRelease(optionsDictionary); 
    } 

    return securityError; 
} 

私の接続は以下のエラーで失敗しています。

{ 
    NSErrorFailingURLKey = "https://myIpdaddress/Service1.svc/test/random"; 
    NSErrorFailingURLStringKey = "https://myIpdaddress/Service1.svc/test/random"; 
    NSLocalizedDescription = "The server \U201cmyIpdaddress\U201d requires a client certificate."; 
    NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1206 \"The server \U201cmyIpdaddress\U201d requires a client certificate.\" UserInfo=0x4b240b0 {NSErrorFailingURLKey=https://myIpdaddress/Service1.svc/test/random, NSErrorFailingURLStringKey=https://myIpdaddress/Service1.svc/test/random, NSLocalizedDescription=The server \U201cmyIpdaddress\U201d requires a client certificate.}"; 
} 

これを再開する方法を教えてください。

答えて

1

私はまったく同じ問題を抱えていました。

「Host」HTTPヘッダーを修正することでした。

私が使用していたものには、ポートと経路の一部が含まれていました。 URLのホスト部分だけを含めるようにこのヘッダーを修正すると、作業が開始されました。

私は間違ったホストヘッダーがあったときにサーバーが自分の身元を拒否していたと思います。「クライアント証明書が必要です」というメッセージは、サーバーが証明書を受け入れなかったことを意味する一般的な応答です。

関連する問題