我猜通过使用 .p12 证书,您指的是在客户端和服务器之间建立相互身份验证。基本上,您必须经过以下步骤(objective-c):
- 创建验证服务器所需的安全对象(根据根 CA 签名验证其签名)和验证客户端(向服务器提供客户端证书以验证其签名)。加载 CA 的 .cer 文件和客户端的 .p12 文件。
- 定义要检索的 URL 资源并创建 NSURLConnection
- 指定要处理的身份验证方法(使用 NSURLConnectionDelegate 回调)
- 处理身份验证质询(使用 NSURLConnectionDelegate 回调)
加载证书文件(服务器的根 CA 证书 + 客户端密钥和证书)
rootCertRef 包含 CA 证书(签署服务器证书的 CA 的根证书)
身份 (SecIdentityRef) 包含向服务器验证客户端所需的客户端密钥和证书。
NSData *rootCertData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@”rootCert” ofType:@”cer”]];
SecCertificateRef rootCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef) rootCertData);
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@“clientCert" ofType:@"p12"]];
NSArray *item = nil;
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@“password", kSecImportExportPassphrase, nil];
SecPKCS12Import((CFDataRef) p12Data , (CFDictionaryRef)dict, (CFArrayRef *)item);
SecIdentityRef identity = (SecIdentityRef)[[item objectAtIndex:0] objectForKey:(id)kSecImportItemIdentity];
配置 URL(你已经做了)
// Create the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://google.com"]];
创建 NSURLConnection >> 将委托设置为 self 必须实现 NSURLConnectionDelegate 才能进行客户身份验证
// Create url connection and fire request asynchronously
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
在回调 canAuthenticateAgainstProtectionSpace 中启用服务器和客户端身份验证
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust])
return YES;
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate])
return YES;
return NO;
}
执行服务器请求的相互认证
-(void) connection:didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
//Authenticate the server
if([[protectionSpace authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) { // Verify method
SecTrustRef trust = [[challenge protectionSpace] serverTrust]; // Create trust object
NSArray *trustArray = [NSArray arrayWithObjects:rootCertRef, nil]; // Add as many certificates as needed
SecTrustSetAnchorCertificates(trust, (CFArrayRef) trustArray ); // Set trust anchors
SecTrustResultType trustResult; // Store trust result in this
SecTrustEvaluate(trust, trustResult); // Evaluate server trust
if(trust_result == kSecTrustResultUnspecified) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:trust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
// handle error;
}
//Send client identity to server for client authentication
if([[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
}