我试图在
IOS 5中实现相互认证,但是我遇到麻烦:
{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
当我在浏览器(FF15)中导入时,生成的client.p12文件工作得很好.所以问题不在前面的步骤中.
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,NULL,NULL); CFArrayRef items = CFArrayCreate(NULL,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”.
有任何想法吗?
谢谢.
解决方法
我写的代码工作完美,问题是服务器端.