HTTPS

 

咱們先來看一下百度百科的解釋:
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,所以加密的詳細內容就須要SSL。 它是一個URI scheme(抽象標識符體系),句法類同http:體系。用於安全的HTTP數據傳輸。https:URL代表它使用了HTTP,但HTTPS存在不一樣於HTTP的默認端口及一個加密/身份驗證層(在HTTP與TCP之間)。這個系統的最初研發由網景公司(Netscape)進行,並內置於其瀏覽器Netscape Navigator中,提供了身份驗證與加密通信方法瀏覽器

簡單來說就是一句話: HTTP + SSL = HTTPS安全

那 HTTP 和 HTTPS 兩者之間到底有什麼區別呢 ?
HTTP(超文本傳輸協議)協議被用於在Web瀏覽器和網站服務器之間傳遞信息。HTTP協議以明文方式發送內容,不提供任何方式的數據加密,若是攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就能夠直接讀懂其中的信息,所以HTTP協議不適合傳輸一些敏感信息,好比信用卡號、密碼等。
爲了解決HTTP協議的這一缺陷,須要使用另外一種協議:安全套接字層超文本傳輸協議HTTPS。爲了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通訊加密。服務器

HTTPS和HTTP的區別主要爲如下四點:
1、https協議須要到ca申請證書,通常免費證書不多,須要交費。
2、http是超文本傳輸協議,信息是明文傳輸,https 則是具備安全性的ssl加密傳輸協議。
3、http和https使用的是徹底不一樣的鏈接方式,用的端口也不同,前者是80,後者是443。
4、http的鏈接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。網絡

那如今確定有些人對SSL好奇咯,咱們如今看看 SSL能提供一些什麼服務呢 ?性能

SSL協議提供的服務主要有哪些
1)認證用戶和服務器,確保數據發送到正確的客戶機和服務器
2)加密數據以防止數據中途被竊取
3)維護數據的完整性,確保數據在傳輸過程當中不被改變。
SSL協議的工做流程
服務器認證階段:
1)客戶端向服務器發送一個開始信息「Hello」以便開始一個新的會話鏈接;
2)服務器根據客戶的信息肯定是否須要生成新的主密鑰,如須要則服務器在響應客戶的「Hello」信息時將包含生成主密鑰所需的信息;
3)客戶根據收到的服務器響應信息,產生一個主密鑰,並用服務器的公開密鑰加密後傳給服務器;
4)服務器恢復該主密鑰,並返回給客戶一個用主密鑰認證的信息,以此讓客戶認證服務器。網站

那 如今咱們來看一下 HTTPS 在使用時 咱們在iOS這一塊須要作一些什麼事情呢 ?google

實現支持HTTPS
首先,須要明確你使用HTTP/HTTPS的用途,由於OSX和iOS平臺提供了多種API,來支持不一樣的用途,官方文檔《Making HTTP and HTTPS Requests》有詳細的說明,而文檔《HTTPS Server Trust Evaluation》則詳細講解了HTTPS驗證相關知識,這裏就很少說了。本文主要講解咱們最經常使用的NSURLConnection支持HTTPS的實現(NSURLSession的實現方法相似,只是要求受權證實的回調不同而已),以及怎麼樣使用AFNetworking這個很是流行的第三方庫來支持HTTPS。本文假設你對HTTP以及NSURLConnection的接口有了足夠的瞭解。
驗證證書的API
相關的Api在Security Framework中,驗證流程以下:
1). 第一步,先獲取須要驗證的信任對象(Trust Object)。這個Trust Object在不一樣的應用場景下獲取的方式都不同,對於NSURLConnection來講,是從delegate方法-connection:willSendRequestForAuthenticationChallenge:回調回來的參數challenge中獲取([challenge.protectionSpace serverTrust])。
2). 使用系統默認驗證方式驗證Trust Object。SecTrustEvaluate會根據Trust Object的驗證策略,一級一級往上,驗證證書鏈上每一級數字簽名的有效性(上一部分有講解),從而評估證書的有效性。
3). 如第二步驗證經過了,通常的安全要求下,就能夠直接驗證經過,進入到下一步:使用Trust Object生成一份憑證([NSURLCredential credentialForTrust:serverTrust]),傳入challenge的sender中([challenge.sender useCredential:cred forAuthenticationChallenge:challenge])處理,創建鏈接。
4). 假若有更強的安全要求,能夠繼續對Trust Object進行更嚴格的驗證。經常使用的方式是在本地導入證書,驗證Trust Object與導入的證書是否匹配。更多的方法能夠查看Enforcing Stricter Server Trust Evaluation,這一部分在講解AFNetworking源碼中會講解到。
5). 假如驗證失敗,取消這次Challenge-Response Authentication驗證流程,拒絕鏈接請求。
ps: 假如是自建證書的,則會跳過第二步,使用第三部進行驗證,由於自建證書的根CA的數字簽名未在操做系統的信任列表中。
iOS受權驗證的API和流程大概瞭解了,下面,咱們看看在NSURLConnection中的代碼實現:
使用NSURLConnection支持HTTPS的實現
// Now start the connection
NSURL * httpsURL = [NSURL URLWithString:@」https://www.google.com「];
self.connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:httpsURL] delegate:self];加密

//回調lua

  • (void)connection:(NSURLConnection )connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge )challenge {
    //1)獲取trust object
    SecTrustRef trust = challenge.protectionSpace.serverTrust;
    SecTrustResultType result;url

    //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];

    }
    }
    上面是代碼是經過系統默認驗證流程來驗證證書的。假如咱們是自建證書的呢?這樣Trust Object裏面服務器的證書由於不是可信任的CA簽發的,因此直接使用SecTrustEvaluate進行驗證是不會成功。又或者,即便服務器返回的證書是信任CA簽發的,又如何肯定這證書就是咱們想要的特定證書?這就須要先在本地導入證書,設置成須要驗證的Anchor Certificate(就是根證書),再調用SecTrustEvaluate來驗證。代碼以下
    //先導入證書
    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];

    }
    }
    建議採用本地導入證書的方式驗證證書,來保證足夠的安全性。更多的驗證方法,請查看官方文檔《HTTPS Server Trust Evaluation》

那 對於熟悉網絡請求的同窗 對於AFNetworking確定不會陌生了,它是使用的時候是怎麼配置HTTPS的呢?

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
//主要用於這種狀況:客戶端請求的是子域名,而證書上的是另一個域名。由於SSL證書上的域名是獨立的,假如證書上註冊的域名是www.google.com,那麼mail.google.com是沒法驗證經過的;固然,有錢能夠註冊通配符的域名
.google.com,但這個仍是比較貴的。
securityPolicy.validatesDomainName = NO;
//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相比於HTTP來講,會有一些性能上的劣勢,可是相對比安全性,就是小巫見大巫了。

相關文章
相關標籤/搜索