iOS內建認證,校正https請求

來源:互聯網
上載者:User

標籤:.com   cfa   ios   root   請求   pre   sel   tty   設定ip   

有些情況處於安全的考慮需要https請求,但是為了防止網域名稱解析很多情況下會使用IP進行訪問。一般的服務不會針對IP去申請認證,所以我們可以自己實現ssl登入過程,保證請求的安全性。

一.首先需要自己本地產生ssl認證以及搭建一個本地服務

Mac apache本地配置ssl認證 及 iOS OTA部署: http://www.jianshu.com/p/bd016015efe7

產生的crt轉換成cer的方法

openssl x509 -in test.crt -out test.cer -outform der

二.實現代碼

初始化NSURLSession,將認證匯入對應的xcode項目中

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration];configuration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;configuration.timeoutIntervalForRequest = 120;NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration                                                 delegate:self                                            delegateQueue:[[NSOperationQueue alloc] init]];

產生的ssl認證需要設定ip,而且校正的時候也會去校正這個ip。但是更多情況下是不去校正這個ip的,因為代碼內部可能只有一個認證,但是服務可能會有多套部署,如果去校正ip,會限制服務的擴充(很多項目都會做自己的DNS策略,ip經常會改變)。

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{    NSString *host = challenge.protectionSpace.host;    BOOL isIp = [self _isIp:host];    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {        if (isIp) {            // Get            NSData *certData =[NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"]];            if (certData) {                SecTrustRef trust = [[challenge protectionSpace] serverTrust];                                NSMutableArray *policies = [NSMutableArray array];
          //如果需要校正IP,需要把下面的注釋開啟,把下面X509這段代碼注釋掉
          //[policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; SecTrustSetPolicies(trust, (__bridge CFArrayRef)policies); SecCertificateRef rootcert = SecCertificateCreateWithData(kCFAllocatorDefault,CFBridgingRetain(certData)); const void *array[1] = { rootcert }; CFArrayRef certs = CFArrayCreate(NULL, array, 1, &kCFTypeArrayCallBacks); int err; SecTrustResultType trustResult = 0; err = SecTrustSetAnchorCertificates(trust, certs); if (err == noErr) { err = SecTrustEvaluate(trust,&trustResult); } BOOL trusted = (err == noErr) && ((trustResult == kSecTrustResultProceed) || (trustResult == kSecTrustResultUnspecified)); if (!trusted) { NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] ; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } else { //如果校正失敗了,就校正一下認證資料,一般不建議走這段邏輯,因為不能夠保證服務是否安全 NSMutableArray *pinnedCertificates = [NSMutableArray array]; [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData)]; SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)pinnedCertificates); NSArray *serverCertificates = [self _certificateTrustChainForServerTrust:trust]; for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) { if ([certData isEqualToData:trustChainCertificate]) { NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] ; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } } } } } else { NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential, credential); } }}- (BOOL)_isIp:(NSString*)aHost{ NSString *regex = @"((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"; NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex]; return [pred evaluateWithObject:aHost];}- (NSArray *)_certificateTrustChainForServerTrust:(SecTrustRef)serverTrust{ CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; } return [NSArray arrayWithArray:trustChain];}

https請求構建

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://127.0.0.1:443/index.html"]];        NSURLSessionDataTask *task = [_session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        completionHandler(((NSHTTPURLResponse*)response).statusCode, data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : nil, error);    }];        [task resume];

網上的例子有很多,但是很多沒有考慮不校正IP的情境。希望本文能夠給大家一個參考

iOS內建認證,校正https請求

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.