https双向认证(AFNetworking 2.x)

AFNetworking 3.0用AFHTTPSessionManager代替了2.6版本中的AFHTTPRequestOperationManager。AFHTTPSessionManager可以调用setSessionDidReceiveAuthenticationChallengeBlock,在这个block内部把自己的p12交给服务器来验证,但是2.x版本中的AFHTTPRequestOperationManager并没有这个block方法,所以2.x版本中有一点变化。

单向验证:验证服务器CA
+(AFHTTPRequestOperationManager *)SignalSSL{
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    NSString *certFilePath = [[NSBundle mainBundle] pathForResource:@"CA" ofType:@"cer"];
    NSData *certData = [NSData dataWithContentsOfFile:certFilePath];
    NSArray *caArray = [NSArray arrayWithObject:certData];
    AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    policy.allowInvalidCertificates = YES;
    [policy setPinnedCertificates:caArray];
    policy.validatesDomainName = YES;
    manager.securityPolicy = policy;

    [manager.requestSerializer setValue:@"header" forHTTPHeaderField:@"Accept-Language"];
 
    return manager;
}
双向验证:客户端验证服务器部分与上面单向验证相同,不同的是重写AFURLConnectionOperation中的代理
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
   SecIdentityRef identity = NULL;
   SecTrustRef trust = NULL;
   NSString *p12Str = [[NSBundle mainBundle] pathForResource:@"p12证书" ofType:@"p12"];
   NSData *PKCS12Data = [NSData dataWithContentsOfFile:certFilePath];
   [self extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];
   // extract the ideneity from the certificate
   [self extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data];
   SecCertificateRef certificate = NULL;
   SecIdentityCopyCertificate (identity, &certificate);
   
   NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistencePermanent];
   
   [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
   //
}
-(BOOL)extractIdentity:(SecIdentityRef*)outIdentity andTrust:(SecTrustRef *)outTrust fromPKCS12Data:(NSData *)inPKCS12Data {
   OSStatus securityError = errSecSuccess;
   //client certificate password
   NSDictionary *optionsDictionary = [NSDictionary dictionaryWithObject:@"p12pwd"
                                                                 forKey:(__bridge id)kSecImportExportPassphrase];
   
   CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
   securityError = SecPKCS12Import((__bridge CFDataRef)inPKCS12Data,(__bridge CFDictionaryRef)optionsDictionary,&items);
   
   if(securityError == 0) {
       CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0);
       const void*tempIdentity =NULL;
       tempIdentity= CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity);
       *outIdentity = (SecIdentityRef)tempIdentity;
       const void*tempTrust =NULL;
       tempTrust = CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);
       *outTrust = (SecTrustRef)tempTrust;
   } else {
       NSLog(@"Failedwith error code %d",(int)securityError);
       return NO;
   }
   return YES;
}

这样AFNetworking3.0以下版本的https双向通道就配置完成了

你可能感兴趣的:(https双向认证(AFNetworking 2.x))