iOS适配HTTPS 双向认证 (AFNetworking)

来源:互联网 发布:网络直播的好处 编辑:程序博客网 时间:2024/05/16 10:55

static AFHTTPRequestOperationManager *rom =nil;

我是封装了一下 Sharemanger, 

rom.securityPolicy = [self customSecurityPolicy]; //设置HTTPS的验证类 

 

复制代码
+ (AFSecurityPolicy*)customSecurityPolicy{        // /先导入证书    在这加证书,一般情况适用于单项认证//    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"igoda" ofType:@"cer"];//证书的路径//    //    NSData *certData = [NSData dataWithContentsOfFile:cerPath];//    if (ISNULL(certData)) {//        return nil;//    }    // AFSSLPinningModeCertificate 使用证书验证模式        AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];        // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO        // 如果是需要验证自建证书,需要设置为YES        securityPolicy.allowInvalidCertificates = YES;        //validatesDomainName 是否需要验证域名,默认为YES;        //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。        //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。        //如置为NO,建议自己添加对应域名的校验逻辑。        securityPolicy.validatesDomainName = NO;    //    securityPolicy.pinnedCertificates = @[certData];        return securityPolicy;    }
复制代码

然后在  

AFURLConnectionOperation.m  中加方法

复制代码
- (OSStatus)extractIdentity:(CFDataRef)inP12Data toIdentity:(SecIdentityRef*)identity {        OSStatus securityError = errSecSuccess;                CFStringRef password = CFSTR("igoda2016");        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;    }
复制代码

然后将验证HTTPS的代理方法 

- (void)connection:(NSURLConnection *)connection

willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge  内容替换一下,要加自己证书  和证书的密码

方法内容全部替换为 :

复制代码
 NSString *thePath = [[NSBundle mainBundle] pathForResource:@"goda" 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 toIdentity:&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];
复制代码

到这就大功告成

 用抓包工具 Charles试试:

0 0
原创粉丝点击