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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM