2012-09-20 2 views
12

내가 IOS 5에서 상호 인증을 구현하기 위해 노력하고있어하지만 난 문제에 봉착 : 나는 (자기 중 하나가 서명 또는 가짜 CA의 I와 서버의 키, 인증서 및 PKCS12를 생성IOS 상호 인증

{NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1200 \"An SSL error has occurred and a secure connection to the server cannot be made.\" UserInfo=0x18d830 {NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., _kCFNetworkCFStreamSSLErrorOriginalValue=-9800, _kCFStreamPropertySSLClientCertificateState=0, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLStringKey=https://192.168.24.110:8081/t01.json, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0xceaa2d0>, NSErrorFailingURLKey=https://192.168.24.110:8081/t01.json} 

을 나는 브라우저 (FF15)에서 가져올 때

openssl genrsa -out client.key 1024 
openssl req -new -key client.key -out client.csr 

self-signed 
openssl req -new -key ca.key -x509 -days 1095 -out ca.crt 

CA signed 
openssl x509 -req -days 365 -in client.csr -CA server.crt -CAkey server.key -CAcreateserial -out client.crt 

CRT to PEM 
openssl x509 -in client.crt -out client.der -outform DER 
openssl x509 -in client.der -inform DER -out client.pem -outform PEM 

PEM TO PKCS 12 
openssl pkcs12 -export -in client.pem -inkey client.key -out client.p12 

결과이 client.p12 파일이 완벽하게 작동합니다 : 항상 이런 식으로 그 문제)와 클라이언트를 얻었다. 따라서 문제는 이전 단계에서 찾을 수 없습니다.

IOS 측 나는이 ​​예를 시도 : http://vanjakom.wordpress.com/tag/nsurlconnection/

을 그리고 이것은 내가 그 예를 작동하지 않는 발견했을 때 내가 쓴 것입니다 : 나는 클라이언트를 autheticate 수없는 두 경우 모두

// Returns an array containing the certificate 
- (CFArrayRef)getCertificate:(SecIdentityRef) identity { 
    SecCertificateRef certificate = nil; 

    SecIdentityCopyCertificate(identity, &certificate); 
    SecCertificateRef certs[1] = { certificate }; 

    CFArrayRef array = CFArrayCreate(NULL, (const void **) certs, 1, NULL); 

    SecPolicyRef myPolicy = SecPolicyCreateBasicX509(); 
    SecTrustRef myTrust; 

    OSStatus status = SecTrustCreateWithCertificates(array, myPolicy, &myTrust); 
    if (status == noErr) { 
     NSLog(@"No Err creating certificate"); 
    } else { 
     NSLog(@"Possible Err Creating certificate"); 
    } 
    return array; 
} 

// Returns the identity 
- (SecIdentityRef)getClientCertificate { 
    SecIdentityRef identityApp = nil; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectoryPath = [paths objectAtIndex:0]; 
    NSString *myFilePath = [documentsDirectoryPath stringByAppendingPathComponent:@"file12.p12"]; 
    NSData *PKCS12Data = [NSData dataWithContentsOfFile:myFilePath]; 

    CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data; 
    CFStringRef password = CFSTR("password"); 
    const void *keys[] = { kSecImportExportPassphrase };//kSecImportExportPassphrase }; 
    const void *values[] = { password }; 
    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL); 
    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL); 
    OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items); 
    CFRelease(options); 
    CFRelease(password); 
    if (securityError == errSecSuccess) { 
     NSLog(@"Success opening p12 certificate. Items: %ld", CFArrayGetCount(items)); 
     CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0); 
     identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity); 
    } else { 
     NSLog(@"Error opening Certificate."); 
    } 

    return identityApp; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { 
    if ([challenge previousFailureCount] == 0) { 
     SecIdentityRef identity = [self getClientCertificate]; // Go get a SecIdentityRef 
     CFArrayRef certs = [self getCertificate:identity]; // Get an array of certificates 
     // Convert the CFArrayRef to a NSArray 
     NSArray *myArray = (__bridge NSArray *)certs; 

     // Create the NSURLCredential 
     NSURLCredential *newCredential = [NSURLCredential credentialWithIdentity:identity certificates:myArray persistence:NSURLCredentialPersistencePermanent]; 

     // Send 
     [challenge.sender useCredential:newCredential forAuthenticationChallenge:challenge];  
    } else { 
     // Failed 
     [[challenge sender] cancelAuthenticationChallenge:challenge]; 
    } 
} 

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace 
{ 
    return YES; 
} 

합니다. 또한 장치 (iPhone/iPad)에 server.crt 인증서를 설치했지만 "Error Domain = NSURLErrorDomain Code = -1200"을 계속 수신합니다.

아이디어가 있으십니까? 감사합니다.

+0

내가 작성한 코드는 완벽하게 작동하지만 문제는 서버 쪽이었습니다. – lontra

+1

솔루션을 답변으로 게시하고 그 옆에있는 큰 체크 표시를 눌러 승인해야합니다. 여기서 해결 된 질문을 표시하는 방법입니다. –

답변

3

제가 작성한 코드는 완벽하게 작동합니다. 문제는 서버 쪽이었습니다.

+1

서버 측 문제는 무엇입니까? 나는 같은 문제를 겪고있다. –