標籤:
一、伺服器需要做的事情:
1、要注意 App Transport Security 要求 TLS 1.2,
2、而且它要求網站使用支援forward secrecy協議的密碼。
3、認證也要求是符合ATS規格的,ATS只信任知名CA頒發的認證,小公司所使用的 self signed certificate,還是會被ATS攔截。。因此謹慎檢查與你的應用互動的伺服器是不是符合ATS的要求非常重要。
二、用戶端可使用四種方案:
1、全部Https 2、倆者混合,個別不符合 3、 全部禁用Https
4、 預設禁用https, 但是對於特殊網站,開啟Https
1. |
HTTPS Only (只有HTTPS,所有情況下都使用ATS) |
如果你的應用只基於支援HTTPS的伺服器,那麼你太幸運了。你的應用不需要做任何改變。但是,注意App Transport Security要求TLS 1.2而且它要求網站使用支援forward secrecy協議的密碼。認證也要求是符合ATS規格的。因此謹慎檢查與你的應用互動的伺服器是不是符合ATS的要求非常重要。 |
2. |
Mix & Match(混合) |
你的應用與一個不符合ATS要求的伺服器工作是很有可能的。在這種情況下,你需要告訴作業系統哪些網站是涉及到的然後在你的應用的 Info.plist檔案中指明哪些要求沒有達到。 |
3. |
Opt Out(禁用ATS) |
如果你在建立一個網頁瀏覽器,那麼你有一個更大的麻煩。因為你不可能知道你的使用者將要訪問那個網頁,你不可能指明這些網頁是否支援ATS要求且在HTTPS上傳輸。在這種情況下,除了全部撤銷 App Transport Security 沒有其它辦法。 |
4. |
Opt Out With Exceptions(除特殊情況外,都不使用ATS) |
當你的應用撤消了App Transport Security,,但同時定義了一些例外。這非常有用就是當你的應用從很多的伺服器上取資料,但是也要與一個你可控的API互動。在這種情況下,在應用的Info.plist檔案中指定任何載入都是被允許的,但是你也指定了一個或多個例外來表明哪些是必須要求 App Transport Security的。 |
使用NSURLConnection支援HTTPS的實現
// Now start the connection
NSURL * httpsURL = [NSURL URLWithString:@"https://www.google.com"];
self.connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:httpsURL] delegate:self];
//回調
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
//1)擷取trust object
SecTrustRef trust = challenge.protectionSpace.serverTrust;
SecTrustResultType result;
//2)SecTrustEvaluate對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];
}
}
使用AFNetworking來支援HTTPS
AFNetworking是iOS/OSX開發最流行的第三方開源庫之一,其作者是非常著名的iOS/OSX開發人員Mattt Thompson,其部落格NSHipster也是iOS/OSX開發人員學習和開闊技術視野的好地方。AFNetworking已經將上面的邏輯代碼封裝好,甚至更完善,在AFSecurityPolicy檔案中,有興趣可以閱讀這個模組的代碼;
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;
這就是AFNetworking的支援HTTPS的主要配置說明,AFHTTPSessionManager與之基本一致,就不重複了。
用戶端驗證Https認證, 有伺服器憑證和用戶端自建認證倆個認證來源, 到時候由伺服器同學確定。
相關知識參考:
https://github.com/ChenYilong/iOS9AdaptationTips#1https-only-%E5%8F%AA%E6%9C%89https%E6%89%80%E6%9C%89%E6%83%85%E5%86%B5%E4%B8%8B%E9%83%BD%E4%BD%BF%E7%94%A8ats
http://mp.weixin.qq.com/s?__biz=MzAxMzE2Mjc2Ng==&mid=211889548&idx=1&sn=8eb4da781c32a7fd51c3ad552347f322&scene=23&srcid=0922zkxfLe07GKN3NfLh8b6k#rd
iOS9 Https技術預研