ios AFNetworking https 双向证书验证实现


因为公司对接口做了安全处理,部分接口实现https 加密,双向验证就是 ,服务端要验证客户端,客户端也要验证服务器端,通过证书验证

首先,因为用的是AFNetworking实现的网络请求,已经自带https 服务,只需要加以下代码


    //设置https 请求
    self.securityPolicy=[AFSecurityPolicypolicyWithPinningMode:AFSSLPinningModePublicKey];
        self.securityPolicy.allowInvalidCertificates = YES;
        self.securityPolicy.validatesDomainName = NO;


第二部倒入服务器给的p12 证书,如果没有给p12证书,可以自己转一下,首先把服务端的证书client.p12 导入到客户端里,在afnetworking ,然后在 AFURLConnectionOperation.m中加入以下方法

- (OSStatus)extractIdentity:(CFDataRef)inP12Data :(SecIdentityRef*)identity {
    OSStatus securityError = errSecSuccess;

    CFStringRef password = CFSTR("clic1234");//证书密码
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };

    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    securityError = SecPKCS12Import(inP12Data, options, &items);
    if (securityError == 0)
    {
        CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
        *identity = (SecIdentityRef)tempIdentity;
    }
    if (options) {
        CFRelease(options);
    }
    return securityError;
}

**把AFURLConnectionOperation.m中的
- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
替换成**

- (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{

                        NSString *thePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
                 //倒入证书       NSLog(@"thePath===========%@",thePath);
                        NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
                        CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;

                        SecIdentityRef identity = NULL;
                        // extract the ideneity from the certificate
                        [self extractIdentity :inPKCS12Data :&identity];

                        SecCertificateRef certificate = NULL;
                        SecIdentityCopyCertificate (identity, &certificate);

                        const void *certs[] = {certificate};
//                        CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);
                        // create a credential from the certificate and ideneity, then reply to the challenge with the credential
                        //NSLog(@"identity=========%@",identity);
                        NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistencePermanent];

//           credential = [NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];

            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];


}

然后就可以进行双向验证了,
参考文章:http://ccana.blog.51cto.com/9993118/1647256
http://kyfxbl.iteye.com/blog/2066571

你可能感兴趣的:(ios)