2012-09-20 6 views
12

Ich versuche, die gegenseitige Authentifizierung in IOS 5 zu implementieren, aber ich habe Probleme:IOS Mutual Authentication

{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} 

I erzeugten Schlüssel, Zertifikate und pkcs12 für Server (entweder selbst signiert oder mit einem gefälschten CA I bekam immer das Problem) und Client auf diese Weise:

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 

die resultierende client.p12 Datei funktioniert perfekt, wenn ich es im Browser (FF15) importieren. Daher ist das Problem in den vorherigen Schritten nicht zu finden.

IOS Seite habe ich versucht, dieses Beispiel: http://vanjakom.wordpress.com/tag/nsurlconnection/

und das ist, was ich geschrieben habe, wenn ich das Beispiel fand nicht funktioniert:

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

In beiden Fällen, die ich nicht den Client autheticate kann. Außerdem habe ich auch das server.crt-Zertifikat auf dem Gerät (iPhone/iPad) installiert, aber ich bekomme weiterhin "Error Domain = NSURLErrorDomain Code = -1200".

Irgendwelche Ideen? Danke.

+0

Der Code, den ich schrieb funktioniert einwandfrei, das Problem war Server-Seite. – lontra

+1

Sie sollten Ihre Lösung als Antwort posten und akzeptieren, indem Sie auf das große Häkchen daneben klicken. Auf diese Weise markieren Sie Fragen als gelöst. –

Antwort

3

Der Code, den ich schrieb funktioniert einwandfrei, das Problem war Server-Seite.

+1

können Sie bitte hinzufügen, was das serverseitige Problem war? Ich habe das gleiche Problem –