Translate

bloggerads內文

2017年4月16日 星期日

IOS 使用HTTPS連線 (NSURLConnection & AFNetworking )

由於Apple 之後有可能會使用全面使用https來連線,因此在這整理了2種方式.


1.使用NSURLConnection來實現HTTPS連線

//先導入證書 NSString * cerPath = ...; //證書的路径 NSData * cerData = [NSData dataWithContentsOfFile:cerPath]; SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)(cerData)); self.trustedCertificates = @[CFBridgingRelease(certificate)]; - (void)connection:(NSURLConnection *)connection
willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { //1)獲取trust object SecTrustRef trust = challenge.protectionSpace.serverTrust; SecTrustResultType result; //注意:這裡將之前導入的證書設置成下面驗證的Trust Object的anchor certificate SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)self.trustedCertificates); //2)SecTrustEvaluate會查找前面SecTrustSetAnchorCertificates設置的證書或是系統預設提供的證書,對trust進行驗證 OSStatus status = SecTrustEvaluate(trust, &result); if (status == errSecSuccess && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) { //3)驗證成功,生成NSURLCredential憑證cred,告知challenge的sender使用這個憑證來繼續連接 NSURLCredential *cred = [NSURLCredential credentialForTrust:trust]; [challenge.sender useCredential:cred forAuthenticationChallenge:challenge]; } else { //5)驗證失敗,取消這次驗證流程 [challenge.sender cancelAuthenticationChallenge:challenge]; } }


2.使用AFNetworking來實現HTTPS連線

NSURL * url = [NSURL URLWithString:@"https://www.google.com"]; AFHTTPRequestOperationManager * requestOperationManager = [[AFHTTPRequestOperationManager alloc]
initWithBaseURL:url]; dispatch_queue_t requestQueue =
dispatch_create_serial_queue_for_name("kRequestCompletionQueue"); requestOperationManager.completionQueue = requestQueue; AFSecurityPolicy * securityPolicy = [AFSecurityPolicy
policyWithPinningMode:AFSSLPinningModeCertificate]; //allowInvalidCertificates 是否允許無效證書(也就是自建的證書),預設為NO //如果是需要驗證自建證書,需要設置為YES securityPolicy.allowInvalidCertificates = YES; //validatesDomainName 是否需要驗證網域名,預設為YES; //假如證書的域名與你請求的網域名不一致,需把該項設置為NO;如設成NO的話,即服務器使用其他可信任機構頒發的證書,也可以建立連接,這個非常危險,建議打開。 //置為NO,主要用於這種情況:客戶端請求的是子網域名,而證書上的是另外一個網域名。因為SSL證書上的網域名是獨立的,假如證書上註冊的域名是www.google.com,那麼mail.google.com是無法驗證通過的;當然,有錢可以註冊通配符的域名*.google.com,但這個還是比較貴的。 //如置為NO,建議自己添加對應網域名的校驗邏輯。 securityPolicy.validatesDomainName = YES; //validatesCertificateChain 是否驗證整個證書鏈,預設為YES //設置為YES,會將服務器返回的Trust Object上的證書鏈與本地導入的證書進行對比,這就意味著,假如你的證書鍊是這樣的: //GeoTrust Global CA // Google Internet Authority G2 // *.google.com //那麼,除了導入*.google.com之外,還需要導入證書鏈上所有的CA證書(GeoTrust Global CA, Google Internet Authority G2); //如是自建證書的時候,可以設置為YES,增強安全性;假如是信任的CA所簽發的證書,則建議關閉該驗證,因為整個證書鏈一一比對是完全沒有必要(請查看源代碼); securityPolicy.validatesCertificateChain = NO; requestOperationManager.securityPolicy = securityPolicy;

沒有留言:

張貼留言