iOS適配HTTPS 雙向認證 (AFNetworking)

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試試:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章