iOS安全系列之 HTTPS

本文參考鏈接:
Jamin
HTTPS信任證書的三種方法

在2016年底, Apple要求所有App適配App Transport Security,簡(jiǎn)單的說就是除了特殊情況外月培,App跟服務(wù)端通信必須使用HTTPS協(xié)議,否則將阻止明文的HTTP請(qǐng)求恩急,從2017年1月1日起杉畜,所有的新提交app默認(rèn)是不允許使用 Allow Arbitrary Loads來繞過ATS限制的。

但是在2017年1月11日衷恭,Apple發(fā)布聲明宣布延長(zhǎng)這個(gè)時(shí)限寻行,提供開發(fā)者更多的時(shí)間來準(zhǔn)備適應(yīng),目前Apple仍未發(fā)布最新的截止日期匾荆。

雖然這個(gè)消息讓很多iOS開發(fā)者長(zhǎng)出一口氣拌蜘,至少目前不必?fù)?dān)心了,但是如果你不準(zhǔn)備好HTTPS牙丽,那么它終究是你頭頂上的達(dá)摩克利斯之劍简卧,作為一名有追求的iOS開發(fā)者,有必要更深入的了解HTTPS烤芦。

引讀: 互聯(lián)網(wǎng)全站HTTPS的時(shí)代已經(jīng)到來

一. HTTPS

其實(shí)HTTPS從最終的數(shù)據(jù)解析的角度举娩,與HTTP沒有任何的區(qū)別,HTTPS就是將HTTP協(xié)議數(shù)據(jù)包放到SSL/TSL層加密后构罗,在TCP/IP層組成IP數(shù)據(jù)報(bào)去傳輸铜涉,以此保證傳輸數(shù)據(jù)的安全;而對(duì)于接收端遂唧,在SSL/TSL將接收的數(shù)據(jù)包解密之后芙代,將數(shù)據(jù)傳給HTTP協(xié)議層,就是普通的HTTP數(shù)據(jù)盖彭。HTTP和SSL/TSL都處于OSI模型的應(yīng)用層纹烹。從HTTP切換到HTTPS是一個(gè)非常簡(jiǎn)單的過程页滚,在做具體的切換操作之前,我們需要了解幾個(gè)概念:

SSL/TSL

關(guān)于SSL/TSL铺呵,阮一峰的兩篇博客文章做了很好的介紹:

簡(jiǎn)單的來說裹驰,SSL/TSL通過四次握手,主要交換三個(gè)信息:

  1. 數(shù)字證書:該證書包含了公鑰等信息片挂,一般是由服務(wù)器發(fā)給客戶端幻林,接收方通過驗(yàn)證這個(gè)證書是不是由信賴的CA簽發(fā),或者與本地的證書相對(duì)比音念,來判斷證書是否可信滋将;假如需要雙向驗(yàn)證,則服務(wù)器和客戶端都需要發(fā)送數(shù)字證書給對(duì)方驗(yàn)證症昏。

  2. 三個(gè)隨機(jī)數(shù):這三個(gè)隨機(jī)數(shù)構(gòu)成了后續(xù)通信過程中用來對(duì)數(shù)據(jù)進(jìn)行對(duì)稱加密解密的“對(duì)話密鑰”。首先客戶端先發(fā)第一個(gè)隨機(jī)數(shù)N1父丰,然后服務(wù)器回了第二個(gè)隨機(jī)數(shù)N2(這個(gè)過程同時(shí)把之前提到的證書發(fā)給客戶端)肝谭,這兩個(gè)隨機(jī)數(shù)都是明文的;而第三個(gè)隨機(jī)數(shù)N3(這個(gè)隨機(jī)數(shù)被稱為Premaster secret)蛾扇,客戶端用數(shù)字證書的公鑰進(jìn)行非對(duì)稱加密攘烛,發(fā)給服務(wù)器;而服務(wù)器用只有自己知道的私鑰來解密镀首,獲取第三個(gè)隨機(jī)數(shù)坟漱。只有服務(wù)端和客戶端都有了三個(gè)隨機(jī)數(shù)N1+N2+N3,然后兩端就使用這三個(gè)隨機(jī)數(shù)來生成“對(duì)話密鑰”更哄,在此之后的通信都是使用這個(gè)“對(duì)話密鑰”來進(jìn)行對(duì)稱加密解密芋齿。因?yàn)檫@個(gè)過程中,服務(wù)端的私鑰只用來解密第三個(gè)隨機(jī)數(shù)成翩,從來沒有在網(wǎng)絡(luò)中傳輸過觅捆,這樣的話,只要私鑰沒有被泄露麻敌,那么數(shù)據(jù)就是安全的栅炒。

  3. 加密通信協(xié)議:就是雙方商量使用哪一種加密方式,假如兩者支持的加密方式不匹配术羔,則無法進(jìn)行通信赢赊。

有個(gè)常見的問題,關(guān)于隨機(jī)數(shù)為什么要三個(gè)级历?只最后一個(gè)隨機(jī)數(shù)N3不可以么释移?

這是由于SSL/TLS設(shè)計(jì),就假設(shè)服務(wù)器不相信所有的客戶端都能夠提供完全隨機(jī)數(shù)寥殖,假如某個(gè)客戶端提供的隨機(jī)數(shù)不隨機(jī)的話秀鞭,就大大增加了“對(duì)話密鑰”被破解的風(fēng)險(xiǎn)趋观,所以由三組隨機(jī)數(shù)組成最后的隨機(jī)數(shù),保證了隨機(jī)數(shù)的隨機(jī)性锋边,以此來保證每次生成的“對(duì)話密鑰”安全性皱坛。

數(shù)字證書

數(shù)字證書是一個(gè)電子文檔,其中包含了持有者的信息豆巨、公鑰以及證明該證書有效的數(shù)字簽名剩辟。而數(shù)字證書以及相關(guān)的公鑰管理和驗(yàn)證等技術(shù)組成了PKI(公鑰基礎(chǔ)設(shè)施)規(guī)范體系。一般來說往扔,數(shù)字證書是由數(shù)字證書認(rèn)證機(jī)構(gòu)(Certificate authority贩猎,即CA)來負(fù)責(zé)簽發(fā)和管理,并承擔(dān)PKI體系中公鑰合法性的檢驗(yàn)責(zé)任萍膛;數(shù)字證書的類型有很多吭服,而HTTPS使用的是SSL證書。

怎么來驗(yàn)證數(shù)字證書是由CA簽發(fā)的蝗罗,而不是第三方偽造的呢艇棕? 在回答這個(gè)問題前,我們需要先了解CA的組織結(jié)構(gòu)串塑。首先沼琉,CA組織結(jié)構(gòu)中,最頂層的就是根CA桩匪,根CA下可以授權(quán)給多個(gè)二級(jí)CA打瘪,而二級(jí)CA又可以授權(quán)多個(gè)三級(jí)CA,所以CA的組織結(jié)構(gòu)是一個(gè)樹結(jié)構(gòu)傻昙。了解了CA的組織結(jié)構(gòu)后闺骚,來看看數(shù)字證書的簽發(fā)流程:

數(shù)字證書的簽發(fā)機(jī)構(gòu)CA,在接收到申請(qǐng)者的資料后進(jìn)行核對(duì)并確定信息的真實(shí)有效妆档,然后就會(huì)制作一份符合X.509標(biāo)準(zhǔn)的文件葛碧。證書中的證書內(nèi)容包括了持有者信息和公鑰等都是由申請(qǐng)者提供的,而數(shù)字簽名則是CA機(jī)構(gòu)對(duì)證書內(nèi)容進(jìn)行hash加密后等到的过吻,而這個(gè)數(shù)字簽名就是我們驗(yàn)證證書是否是有可信CA簽發(fā)的數(shù)據(jù)进泼。

接收端接到一份數(shù)字證書Cer1后,對(duì)證書的內(nèi)容做Hash等到H1纤虽;然后在簽發(fā)該證書的機(jī)構(gòu)CA1的數(shù)字證書中找到公鑰乳绕,對(duì)證書上數(shù)字簽名進(jìn)行解密,得到證書Cer1簽名的Hash摘要H2逼纸;對(duì)比H1和H2洋措,假如相等,則表示證書沒有被篡改杰刽。但這個(gè)時(shí)候還是不知道CA是否是合法的菠发,我們看到上圖中有CA機(jī)構(gòu)的數(shù)字證書王滤,這個(gè)證書是公開的,所有人都可以獲取到滓鸠。而這個(gè)證書中的數(shù)字簽名是上一級(jí)生成的雁乡,所以可以這樣一直遞歸驗(yàn)證下去,直到根CA糜俗。根CA是自驗(yàn)證的踱稍,即他的數(shù)字簽名是由自己的私鑰來生成的。合法的根CA會(huì)被瀏覽器和操作系統(tǒng)加入到權(quán)威信任CA列表中悠抹,這樣就完成了最終的驗(yàn)證珠月。所以,一定要保護(hù)好自己環(huán)境(瀏覽器/操作系統(tǒng))中根CA信任列表楔敌,信任了根CA就表示信任所有根CA下所有子級(jí)CA所簽發(fā)的證書啤挎,不要隨便添加根CA證書。

了解了上面兩個(gè)概念之后卵凑,對(duì)HTTPS就有了個(gè)初步的了解庆聘,下面我們看如何在iOS上實(shí)現(xiàn)對(duì)HTTPS的支持。

二. 實(shí)現(xiàn)APP支持HTTPS

首先氛谜,需要明確你使用HTTP/HTTPS的用途,因?yàn)镺SX和iOS平臺(tái)提供了多種API区端,來支持不同的用途值漫,官方文檔《Making HTTP and HTTPS Requests》有詳細(xì)的說明,而文檔《HTTPS Server Trust Evaluation》則詳細(xì)講解了HTTPS驗(yàn)證相關(guān)知識(shí)织盼,這里就不多說了杨何。本文主要講解我們最常用的NSURLSession支持HTTPS的實(shí)現(xiàn),以及怎么樣使用AFNetworking這個(gè)非常流行的第三方庫(kù)來支持HTTPS沥邻。本文假設(shè)你對(duì)HTTP以及NSURLSession的接口有了足夠的了解危虱。

使用NSURLSession來支持HTTPS
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];  
_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];

NSURL *url = [NSURL URLWithString:@"https://域名"];  
 // 發(fā)起數(shù)據(jù)任務(wù)  
[[self.session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {  
NSLog(@"%@---%@",response,[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);  

// 在代理方法中實(shí)現(xiàn)證書的信任
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {
    /*
     <NSURLProtectionSpace: 0x7fef2b686e20>:
     Host:mail.itcast.cn,
     Server:https,
     Auth-Scheme:NSURLAuthenticationMethodServerTrust,
     */
    // 判斷是否是信任服務(wù)器證書
    if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
        // 告訴服務(wù)器,客戶端信任證書
        // 創(chuàng)建憑據(jù)對(duì)象
        NSURLCredential *credntial = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
        // 通過completionHandler告訴服務(wù)器信任證書
        completionHandler(NSURLSessionAuthChallengeUseCredential,credntial);
    }
    NSLog(@"protectionSpace = %@",challenge.protectionSpace);
}

上面是代碼是通過系統(tǒng)默認(rèn)驗(yàn)證流程來驗(yàn)證證書的唐全。假如我們是自建證書的呢埃跷?這樣的話服務(wù)器的證書因?yàn)椴皇强尚湃蔚腃A簽發(fā)的,所以直接使用進(jìn)行驗(yàn)證是不會(huì)成功的邮利。又或者弥雹,即使服務(wù)器返回的證書是信任CA簽發(fā)的,又如何確定這證書就是我們想要的特定證書延届?這就需要先在本地導(dǎo)入證書剪勿,再驗(yàn)證。

使用AFNetworking來支持HTTPS

AFNetworking是iOS/OSX開發(fā)最流行的第三方開源庫(kù)之一方庭,其作者是非常著名的iOS/OSX開發(fā)者Mattt Thompson厕吉,其博客NSHipster也是iOS/OSX開發(fā)者學(xué)習(xí)和開闊技術(shù)視野的好地方酱固。AFNetworking已經(jīng)將上面的邏輯代碼封裝好,甚至更完善头朱,在AFSecurityPolicy文件中运悲,有興趣可以閱讀這個(gè)模塊的代碼。 下面是代碼部分:

    // 1.初始化單例類
    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
    mgr.securityPolicy.SSLPinningMode = AFSSLPinningModeCertificate;
    // 2.設(shè)置證書模式
    NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"此處填文件的拓展名"];
    NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
    mgr.securityPolicy.pinnedCertificates = [[NSArray alloc] initWithObjects:cerData, nil];
    // 客戶端是否信任非法證書
    mgr.securityPolicy.allowInvalidCertificates = YES;
    // 是否在證書域字段中驗(yàn)證域名
    [mgr.securityPolicy setValidatesDomainName:NO];

最后建議采用本地導(dǎo)入證書的方式驗(yàn)證證書髓窜,來保證足夠的安全性扇苞。
更多的驗(yàn)證方法,請(qǐng)查看官方文檔《HTTPS Server Trust Evaluation》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寄纵,一起剝皮案震驚了整個(gè)濱河市鳖敷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌程拭,老刑警劉巖定踱,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恃鞋,居然都是意外死亡崖媚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門恤浪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畅哑,“玉大人,你說我怎么就攤上這事水由≤牛” “怎么了?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵砂客,是天一觀的道長(zhǎng)泥张。 經(jīng)常有香客問我,道長(zhǎng)鞠值,這世上最難降的妖魔是什么媚创? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮彤恶,結(jié)果婚禮上钞钙,老公的妹妹穿的比我還像新娘。我一直安慰自己声离,他們只是感情好歇竟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抵恋,像睡著了一般焕议。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天盅安,我揣著相機(jī)與錄音唤锉,去河邊找鬼。 笑死别瞭,一個(gè)胖子當(dāng)著我的面吹牛窿祥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝙寨,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼晒衩,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了墙歪?” 一聲冷哼從身側(cè)響起听系,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎虹菲,沒想到半個(gè)月后靠胜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡毕源,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年浪漠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霎褐。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡址愿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出冻璃,到底是詐尸還是另有隱情响谓,我是刑警寧澤,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布俱饿,位于F島的核電站歌粥,受9級(jí)特大地震影響塌忽,放射性物質(zhì)發(fā)生泄漏拍埠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一土居、第九天 我趴在偏房一處隱蔽的房頂上張望枣购。 院中可真熱鬧,春花似錦擦耀、人聲如沸棉圈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分瘾。三九已至,卻和暖如春吁系,著一層夾襖步出監(jiān)牢的瞬間德召,已是汗流浹背白魂。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留上岗,地道東北人福荸。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肴掷,于是被迫代替她去往敵國(guó)和親敬锐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 作者:Jaminzzhang 如何打造一個(gè)安全的App?這是每一個(gè)移動(dòng)開發(fā)者必須面對(duì)的問題栋烤。在移動(dòng)App開發(fā)領(lǐng)域谒养,...
    __Lex閱讀 788評(píng)論 0 5
  • iOS安全系列之一:HTTPS 2014-10-21 如何打造一個(gè)安全的App?這是每一個(gè)移動(dòng)開發(fā)者必須面對(duì)的問題...
    不作不會(huì)死閱讀 759評(píng)論 0 4
  • HTTPS其實(shí)HTTPS從最終的數(shù)據(jù)解析的角度明郭,與HTTP沒有任何的區(qū)別买窟,HTTPS就是將HTTP協(xié)議數(shù)據(jù)包放到S...
    七維樹閱讀 589評(píng)論 0 2
  • 其實(shí),我對(duì)https以前只有一個(gè)大概的了解薯定,最近工作中遇到一個(gè)問題從而將https協(xié)議做了一個(gè)徹底的學(xué)習(xí)和認(rèn)知始绍,下...
    一條魚的星辰大海閱讀 3,482評(píng)論 0 1
  • 原文地址:iOS安全系列之一:HTTPS 如何打造一個(gè)安全的App?這是每一個(gè)移動(dòng)開發(fā)者必須面對(duì)的問題话侄。在移動(dòng)Ap...
    violafa閱讀 870評(píng)論 0 2