AFNetWorking3.0使用 自我簽署憑證的https請求

來源:互聯網
上載者:User

標籤:dom   nsarray   項目組   bundle   地方   ast   安全   interval   www   

      前幾日,項目組出於安全形度的考慮,要求項目中的請求使用https請求,因為是企業內部使用的app,因此使用了自簽名的認證,而自簽名的認證是不受信任的,所以我們就需要自己來做認證的驗證,包括伺服器驗證用戶端的認證和我們要信任伺服器的認證,SSL雙向認證的原理我這裡就不贅述了,這裡提供兩篇部落格

    iOS安全系列之一:HTTPS: http://oncenote.com/2014/10/21/Security-1-HTTPS/

    iOS安全系列之二:HTTPS進階: http://oncenote.com/2015/09/16/Security-2-HTTPS2/

      從開始準備到調試成功一共用了兩天,查閱了很多網上提供的解決辦法,最後發現很多解決辦法都缺少了一個很重要的過程,就是將用戶端的認證發送到伺服器,讓伺服器驗證我們的身份.如果沒有這一步,那麼我們的請求就會直接被伺服器拒絕導致請求失敗.

  話不多說,相信說多了也沒人看..[手動滑稽]直接上代碼,我這裡用了afn3.0

  準備工作:

    首先要匯入兩個認證, 是兩個  一個是用戶端使用的.p12的認證,另外一個是伺服器端的.cer的認證,將這兩個認證拖入工程中,注意要添加target

    然後要配置ATS,ATS的配置我也提供一篇部落格

    iOS 10 適配 ATS: http://www.jianshu.com/p/36ddc5b009a7

           建立一個類,繼承AFHTTPSessionManager, 我這裡重寫了initWithURL

 1 - (instancetype)initWithBaseURL:(NSURL *)url { 2     self = [super initWithBaseURL:url]; 3     if (self) { 4          5         self.requestSerializer.timeoutInterval = 25; 6         [self.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"]; 7         [self.requestSerializer setValue:url.absoluteString forHTTPHeaderField:@"Referer"]; 8 9 self.securityPolicy = [self getFreeCustomSecurityPolicy];10 11 self.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];12 self.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;13 14 [self setSessionDidBecomeInvalidBlock:^(NSURLSession * _Nonnull session, NSError * _Nonnull error) {15 NSLog(@"setSessionDidBecomeInvalidBlock error : %@",error);16  }];17 if ([url.absoluteString hasPrefix:@"https"]) {//當請求是https時,我們就需要做18 __weak typeof(self) weakSelf = self;19 [self setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession * _Nonnull session, NSURLAuthenticationChallenge * _Nonnull challenge, NSURLCredential *__autoreleasing _Nullable * _Nullable credential) {20 NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;21 __autoreleasing NSURLCredential * credentialSelf =nil;22 if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {//如果有受信任的認證,如果是自簽名的認證,這裡會是NSURLAuthenticationMethodClientCertificate

23 if([weakSelf.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) {
24                         credentialSelf = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];25                         if(credentialSelf) {26                             disposition = NSURLSessionAuthChallengeUseCredential;27                         } else {28                             disposition = NSURLSessionAuthChallengePerformDefaultHandling;29  }30 } else {31 disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;32  }33 } else {//當接收到的是NSURLAuthenticationMethodClientCertificate,我們就將我們的認證發送給伺服器讓其驗證我們的身份34 // client authentication35 SecIdentityRef identity = NULL;36 SecTrustRef trust = NULL;37 NSString *p12 = [[NSBundle mainBundle] pathForResource:@"client"ofType:@"p12"];38 NSFileManager *fileManager =[NSFileManager defaultManager];39 if(![fileManager fileExistsAtPath:p12])40  {41 NSLog(@"client.p12:not exist");42 } else {43 NSData *PKCS12Data = [NSData dataWithContentsOfFile:p12];44 45 if ([weakSelf extractIdentity:&identity andTrust:&trust fromPKCS12Data:PKCS12Data])46  {47 SecCertificateRef certificate = NULL;48 SecIdentityCopyCertificate(identity, &certificate);49 const void*certs[] = {certificate};50 CFArrayRef certArray =CFArrayCreate(kCFAllocatorDefault, certs,1,NULL);51 credentialSelf =[NSURLCredential credentialWithIdentity:identity certificates:(__bridge NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];52 disposition = NSURLSessionAuthChallengeUseCredential;53  }54  }55  }56 *credential = credentialSelf;57 return disposition;58  }];59  }60  }61 return self;62 }63 - (BOOL)extractIdentity:(SecIdentityRef*)outIdentity andTrust:(SecTrustRef *)outTrust fromPKCS12Data:(NSData *)inPKCS12Data {64 OSStatus securityError = errSecSuccess;65 //client certificate password66 NSDictionary*optionsDictionary = [NSDictionary dictionaryWithObject:@"password" forKey:(__bridge id)kSecImportExportPassphrase];67 CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);68 securityError = SecPKCS12Import((__bridge CFDataRef)inPKCS12Data,(__bridge CFDictionaryRef)optionsDictionary,&items);69 70 if(securityError == 0) {71 CFDictionaryRef myIdentityAndTrust =CFArrayGetValueAtIndex(items,0);72 const void*tempIdentity =NULL;73 tempIdentity= CFDictionaryGetValue (myIdentityAndTrust,kSecImportItemIdentity);74 *outIdentity = (SecIdentityRef)tempIdentity;75 const void*tempTrust =NULL;76 tempTrust = CFDictionaryGetValue(myIdentityAndTrust,kSecImportItemTrust);77 *outTrust = (SecTrustRef)tempTrust;78 } else {79 NSLog(@"Failedwith error code %d",(int)securityError);80 return NO;81  }82 return YES;83 }84 - (AFSecurityPolicy *)getFreeCustomSecurityPolicy {85 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];86 NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"server" ofType:@"cer"];87 NSData *certData = [NSData dataWithContentsOfFile:cerPath];88 NSSet *certificateSet = [[NSSet alloc] initWithObjects:certData, nil];89  [securityPolicy setAllowInvalidCertificates:YES];90  [securityPolicy setPinnedCertificates:certificateSet];91  [securityPolicy setValidatesDomainName:NO];92 93 return securityPolicy;94 }

 

這樣設定好了之後就可以發送使用自我簽署憑證的https請求了 

希望可以協助到遇到自我簽署憑證無法發送請求的同學

代碼不太優雅,輕噴,如有錯誤的地方歡迎指正

郵箱:[email protected]

AFNetWorking3.0使用 自我簽署憑證的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.