2012-09-20 42 views
12

我想在iOS 5中實現相互認證,但我有麻煩: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} 

我生成的密鑰,證書和PKCS12服務器(無論是自簽名或用假CA我總是有這個問題)和客戶端是這樣的:

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文件完美的作品,當我導入它在瀏覽器(FF15)。所以這個問題不在前面的步驟中找到。

IOS身邊,我試過了這個例子:http://vanjakom.wordpress.com/tag/nsurlconnection/

,這是我寫的,當我發現,例如不工作:

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

在這兩種情況下,我不能autheticate客戶端。 此外,我還在設備(iPhone/iPad)上安裝了server.crt證書,但我一直收到「錯誤域= NSURLErrorDomain代碼= -1200」。

任何想法? 謝謝。

+0

我寫的代碼完美地工作,問題是服務器端。 – lontra

+1

您應該將您的解決方案作爲答案發布,並通過單擊旁邊的大號複選標記來接受它,這就是您將問題標記爲在此解決的方式。 –

回答

3

我寫的代碼完美工作,問題出在服務器端。

+1

你可以請添加什麼是服務器端問題?我有同樣的問題 –