iOS https

HTTPS協(xié)議

1. 作用

學(xué)名SSL/ TLS 協(xié)議饿敲,不使用SSL/TLS的HTTP通信逝变,就是不加密的通信增淹。所有信息明文傳播,帶來了三大風(fēng)險(xiǎn)漓拾。

(1) 竊聽風(fēng)險(xiǎn)(eavesdropping):第三方可以獲知通信內(nèi)容阁最。
(2) 篡改風(fēng)險(xiǎn)(tampering):第三方可以修改通信內(nèi)容。
(3) 冒充風(fēng)險(xiǎn)(pretending):第三方可以冒充他人身份參與通信骇两。

SSL/TLS協(xié)議是為了解決這三大風(fēng)險(xiǎn)而設(shè)計(jì)的闽撤,希望達(dá)到:

(1) 所有信息都是加密傳播,第三方無法竊聽脯颜。
(2) 具有校驗(yàn)機(jī)制,一旦被篡改贩据,通信雙方會(huì)立刻發(fā)現(xiàn)栋操。
(3) 配備身份證書闸餐,防止身份被冒充。

互聯(lián)網(wǎng)是開放環(huán)境矾芙,通信雙方都是未知身份舍沙,這為協(xié)議的設(shè)計(jì)帶來了很大的難度。而且剔宪,協(xié)議還必須能夠經(jīng)受所有匪夷所思的攻擊拂铡,這使得SSL/TLS協(xié)議變得異常復(fù)雜。

2. 歷史

互聯(lián)網(wǎng)加密通信協(xié)議的歷史葱绒,幾乎與互聯(lián)網(wǎng)一樣長(zhǎng)感帅。

1994年,NetScape公司設(shè)計(jì)了SSL協(xié)議(Secure Sockets Layer)的1.0版地淀,但是未發(fā)布失球。
1995年,NetScape公司發(fā)布SSL 2.0版帮毁,很快發(fā)現(xiàn)有嚴(yán)重漏洞实苞。
1996年,SSL 3.0版問世烈疚,得到大規(guī)模應(yīng)用黔牵。
1999年,互聯(lián)網(wǎng)標(biāo)準(zhǔn)化組織ISOC接替NetScape公司爷肝,發(fā)布了SSL的升級(jí)版[TLS] 1.0版猾浦。
2006年和2008年,TLS進(jìn)行了兩次升級(jí)阶剑,分別為TLS 1.1版和TLS 1.2版跃巡。最新的變動(dòng)是2011年TLS 1.2的[修訂版]。
3. 基本的運(yùn)行過程

SSL/TLS協(xié)議的基本思路是采用公鑰加密法牧愁,也就是說素邪,客戶端先向服務(wù)器端索要公鑰,然后用公鑰加密信息猪半,服務(wù)器收到密文后兔朦,用自己的私鑰解密。

但是磨确,這里有兩個(gè)問題沽甥。
(1)如何保證公鑰不被篡改?
解決方法:將公鑰放在數(shù)字證書中乏奥。只要證書是可信的摆舟,公鑰就是可信的。
(2)公鑰加密計(jì)算量太大,如何減少耗用的時(shí)間恨诱?
解決方法:每一次對(duì)話(session)媳瞪,客戶端和服務(wù)器端都生成一個(gè)"對(duì)話密鑰"(session key),用它來加密信息照宝。由于"對(duì)話密鑰"是對(duì)稱加密蛇受,所以運(yùn)算速度非常快厕鹃,而服務(wù)器公鑰只用于加密"對(duì)話密鑰"本身兢仰,這樣就減少了加密運(yùn)算的消耗時(shí)間。

因此剂碴,SSL/TLS協(xié)議的基本過程是這樣的:

(1) 客戶端向服務(wù)器端索要并驗(yàn)證公鑰把将。
(2) 雙方協(xié)商生成"對(duì)話密鑰"。
(3) 雙方采用"對(duì)話密鑰"進(jìn)行加密通信汗茄。
4. 握手階段的詳細(xì)過程

"握手階段"涉及四次通信秸弛,我們一個(gè)個(gè)來看。需要注意的是洪碳,"握手階段"的所有通信都是明文的递览。

4.1 客戶端發(fā)出請(qǐng)求(ClientHello)

首先,客戶端(通常是瀏覽器)先向服務(wù)器發(fā)出加密通信的請(qǐng)求瞳腌,這被叫做ClientHello請(qǐng)求绞铃。
在這一步,客戶端主要向服務(wù)器提供以下信息嫂侍。

(1) 支持的協(xié)議版本儿捧,比如TLS 1.0版。
(2) 一個(gè)客戶端生成的隨機(jī)數(shù)挑宠,稍后用于生成"對(duì)話密鑰"菲盾。
(3) 支持的加密方法,比如RSA公鑰加密各淀。
(4) 支持的壓縮方法懒鉴。

這里需要注意的是,客戶端發(fā)送的信息之中不包括服務(wù)器的域名碎浇。也就是說临谱,理論上服務(wù)器只能包含一個(gè)網(wǎng)站,否則會(huì)分不清應(yīng)該向客戶端提供哪一個(gè)網(wǎng)站的數(shù)字證書奴璃。這就是為什么通常一臺(tái)服務(wù)器只能有一張數(shù)字證書的原因悉默。
對(duì)于虛擬主機(jī)的用戶來說,這當(dāng)然很不方便苟穆。2006年抄课,TLS協(xié)議加入了一個(gè)Server Name Indication擴(kuò)展唱星,允許客戶端向服務(wù)器提供它所請(qǐng)求的域名。

4.2 服務(wù)器回應(yīng)(SeverHello)

服務(wù)器收到客戶端請(qǐng)求后剖膳,向客戶端發(fā)出回應(yīng)魏颓,這叫做SeverHello。服務(wù)器的回應(yīng)包含以下內(nèi)容吱晒。

(1) 確認(rèn)使用的加密通信協(xié)議版本,比如TLS 1.0版本沦童。如果瀏覽器與服務(wù)器支持的版本不一致仑濒,服務(wù)器關(guān)閉加密通信。
(2) 一個(gè)服務(wù)器生成的隨機(jī)數(shù)偷遗,稍后用于生成"對(duì)話密鑰"墩瞳。
(3) 確認(rèn)使用的加密方法,比如RSA公鑰加密氏豌。
(4) 服務(wù)器證書喉酌。

除了上面這些信息,如果服務(wù)器需要確認(rèn)客戶端的身份泵喘,就會(huì)再包含一項(xiàng)請(qǐng)求泪电,要求客戶端提供"客戶端證書"。比如纪铺,金融機(jī)構(gòu)往往只允許認(rèn)證客戶連入自己的網(wǎng)絡(luò)相速,就會(huì)向正式客戶提供USB密鑰,里面就包含了一張客戶端證書鲜锚。

4.3 客戶端回應(yīng)

客戶端收到服務(wù)器回應(yīng)以后突诬,首先驗(yàn)證服務(wù)器證書。如果證書不是可信機(jī)構(gòu)頒布芜繁、或者證書中的域名與實(shí)際域名不一致旺隙、或者證書已經(jīng)過期,就會(huì)向訪問者顯示一個(gè)警告骏令,由其選擇是否還要繼續(xù)通信蔬捷。
如果證書沒有問題,客戶端就會(huì)從證書中取出服務(wù)器的公鑰伏社。然后抠刺,向服務(wù)器發(fā)送下面三項(xiàng)信息。

(1) 一個(gè)隨機(jī)數(shù)摘昌。該隨機(jī)數(shù)用服務(wù)器公鑰加密速妖,防止被竊聽。
(2) 編碼改變通知聪黎,表示隨后的信息都將用雙方商定的加密方法和密鑰發(fā)送罕容。
(3) 客戶端握手結(jié)束通知备恤,表示客戶端的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時(shí)也是前面發(fā)送的所有內(nèi)容的hash值锦秒,用來供服務(wù)器校驗(yàn)露泊。

上面第一項(xiàng)的隨機(jī)數(shù),是整個(gè)握手階段出現(xiàn)的第三個(gè)隨機(jī)數(shù)惭笑,又稱"pre-master key"。有了它以后沉噩,客戶端和服務(wù)器就同時(shí)有了三個(gè)隨機(jī)數(shù)柱蟀,接著雙方就用事先商定的加密方法川蒙,各自生成本次會(huì)話所用的同一把"會(huì)話密鑰"。
至于為什么一定要用三個(gè)隨機(jī)數(shù)长已,來生成"會(huì)話密鑰",dog250解釋得很好:

"不管是客戶端還是服務(wù)器康聂,都需要隨機(jī)數(shù),這樣生成的密鑰才不會(huì)每次都一樣斤斧。由于SSL協(xié)議中證書是靜態(tài)的早抠,因此十分有必要引入一種隨機(jī)因素來保證協(xié)商出來的密鑰的隨機(jī)性。
對(duì)于RSA密鑰交換算法來說蕊连,pre-master-key本身就是一個(gè)隨機(jī)數(shù)游昼,再加上hello消息中的隨機(jī),三個(gè)隨機(jī)數(shù)通過一個(gè)密鑰導(dǎo)出器最終導(dǎo)出一個(gè)對(duì)稱密鑰烘豌。
pre master的存在在于SSL協(xié)議不信任每個(gè)主機(jī)都能產(chǎn)生完全隨機(jī)的隨機(jī)數(shù)廊佩,如果隨機(jī)數(shù)不隨機(jī)囚聚,那么pre master secret就有可能被猜出來顽铸,那么僅適用pre master secret作為密鑰就不合適了料皇,
因此必須引入新的隨機(jī)因素星压,那么客戶端和服務(wù)器加上pre master secret三個(gè)隨機(jī)數(shù)一同生成的密鑰就不容易被猜出了鬼譬,一個(gè)偽隨機(jī)可能完全不隨機(jī),可是是三個(gè)偽隨機(jī)就十分接近隨機(jī)了竣贪,每增加一個(gè)自由度巩螃,隨機(jī)性增加的可不是一。"

此外,如果前一步汗捡,服務(wù)器要求客戶端證書,客戶端會(huì)在這一步發(fā)送證書及相關(guān)信息扇住。

4.4 服務(wù)器的最后回應(yīng)

服務(wù)器收到客戶端的第三個(gè)隨機(jī)數(shù)pre-master key之后艘蹋,計(jì)算生成本次會(huì)話所用的"會(huì)話密鑰"。然后女阀,向客戶端最后發(fā)送下面信息浸策。

(1)編碼改變通知,表示隨后的信息都將用雙方商定的加密方法和密鑰發(fā)送惫确。
(2)服務(wù)器握手結(jié)束通知蚯舱,表示服務(wù)器的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時(shí)也是前面發(fā)送的所有內(nèi)容的hash值陈肛,用來供客戶端校驗(yàn)凶掰。

至此蜈亩,整個(gè)握手階段全部結(jié)束稚配。接下來港华,客戶端與服務(wù)器進(jìn)入加密通信,就完全是使用普通的HTTP協(xié)議立宜,只不過用"會(huì)話密鑰"加密內(nèi)容橙数。

整個(gè)過程可以用下面這張圖來總結(jié):

HTTPS四次握手

iOS ATS

2016年12月21日蘋果更新了截止日期,宣布延期執(zhí)行ATS支持要求Supporting App Transport Security崖技。
此舉為開發(fā)者提供了更多時(shí)間來做適配和支持钟哥。然而腻贰,對(duì)于iOS開發(fā)者來說,盡早解決HTTPS請(qǐng)求的問題仍為上策播演。
蘋果ATS對(duì)HTTPS證書的要求
啟用ATS必須符合以下標(biāo)準(zhǔn)宾巍,不滿足條件的HTTPS證書,ATS都會(huì)拒絕連接:

  • 服務(wù)器所有的連接使用TLS1.2以上版本
  • HTTPS證書必須使用SHA256以上哈希算法簽名
  • HTTPS證書必須使用RSA 2048位或ECC 256位以上公鑰算法
  • 使用前向加密技術(shù)

此外肄程,蘋果ATS支持CT證書透明选浑,要求開發(fā)者使用支持CT證書透明度的SSL證書,確保SSL證書合法透明拓提,防止中間人攻擊隧膘。

發(fā)送HTTPS請(qǐng)求信任SSL證書寺惫,分為兩種情況:

  1. 如果你的app服務(wù)端安裝的是SSL權(quán)威機(jī)構(gòu)頒發(fā)的CA證書西雀,可以使用系統(tǒng)方法直接實(shí)現(xiàn)信任SSL證書歉摧,關(guān)于Apple對(duì)SSL證書的要求請(qǐng)參考:蘋果官方文檔CertKeyTrustProgGuide
    這種方式不需要在Bundle中引入CA文件,可以交給系統(tǒng)去判斷服務(wù)器端的證書是不是SSL證書再悼,驗(yàn)證過程也不需要我們?nèi)ゾ唧w實(shí)現(xiàn)膝但,網(wǎng)絡(luò)請(qǐng)求部分的代碼無需做修改即可跟束。

  2. 基于AFNetWorking的SSL自制服務(wù)器證書信任處理,重寫AFNetWorking的customSecurityPolicy方法,這里創(chuàng)建了一個(gè)MMDBaseHandle類泳炉,分別對(duì)GET和POST方法進(jìn)行了封裝:

    - (void)requestWithURL:(NSString * _Nonnull) URLString method:(HTTPMethod)method params:(id _Nullable)params block:(nonnull void (^)(MMDResponse * _Nonnull response))block {
    
    NSString *token = [MMDCommonUserModel instance].accessToken;
    NSLog(@"********HTTP REQUEST ACCESSTOKEN:%@", token);
    if (![StringUtils isNullOrEmpty:token]) {
        [self.requestSerializer setValue:token forHTTPHeaderField:@"mmTicket"];
    }
    
    // 加上這行代碼花鹅,https ssl 驗(yàn)證枫浙。
    if(openHttpsSSL) {
        [mgr setSecurityPolicy:[self customSecurityPolicy]];
    }
    
    NSLog(@"********HTTP REQUEST URL: %@%@", self.baseURL.absoluteString, URLString);
    NSLog(@"********HTTP REQUEST PARAMS: %@", params);
    
    switch (method) {
        case GET:
        {
            NSLog(@"暫時(shí)還不支持GET請(qǐng)求方式箩帚,請(qǐng)用POST請(qǐng)求");
            break;
        }
        case POST:
        {
            [self POST:URLString parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
                [self publicHandleResponse:responseObject reqURL:URLString error:nil block:block];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self publicHandleResponse:nil reqURL:URLString error:error block:block];
        }];
        break;
    }
    case PUT:
    {
        NSLog(@"暫時(shí)還不支持PUT請(qǐng)求方式,請(qǐng)用POST請(qǐng)求");
        break;
    }
    case DELETE:
    {
        NSLog(@"暫時(shí)還不支持DELETE請(qǐng)求方式盔然,請(qǐng)用POST請(qǐng)求");
        break;
    }
    }
    }
    
    + (AFSecurityPolicy*)customSecurityPolicy {
    // /先導(dǎo)入證書
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:certificate ofType:@"cer"];//證書的路徑
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
    // AFSSLPinningModeCertificate 使用證書驗(yàn)證模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    
    // allowInvalidCertificates 是否允許無效證書(也就是自建的證書)愈案,默認(rèn)為NO
    // 如果是需要驗(yàn)證自建證書鹅搪,需要設(shè)置為YES
    securityPolicy.allowInvalidCertificates = YES;
    
    //validatesDomainName 是否需要驗(yàn)證域名,默認(rèn)為YES恢准;
    //假如證書的域名與你請(qǐng)求的域名不一致,需把該項(xiàng)設(shè)置為NO涂召;如設(shè)成NO的話眯漩,即服務(wù)器使用其他可信任機(jī)構(gòu)頒發(fā)的證書,也可以建立連接舱卡,這個(gè)非常危險(xiǎn)队萤,建議打開。
    //置為NO舍杜,主要用于這種情況:客戶端請(qǐng)求的是子域名赵辕,而證書上的是另外一個(gè)域名。因?yàn)镾SL證書上的域名是獨(dú)立的饲握,假如證書上注冊(cè)的域名是www.google.com蚕键,那么mail.google.com是無法驗(yàn)證通過的锣光;當(dāng)然,有錢可以注冊(cè)通配符的域名*.google.com誊爹,但這個(gè)還是比較貴的频丘。
    //如置為NO,建議自己添加對(duì)應(yīng)域名的校驗(yàn)邏輯诈火。
    securityPolicy.validatesDomainName = NO;
    
    securityPolicy.pinnedCertificates = @[certData];
    
    return securityPolicy;
    }
    

其中的cerPath就是app bundle中證書路徑,certificate為證書名稱的宏刀崖,僅支持cer格式拍摇,securityPolicy的相關(guān)配置尤為重要,請(qǐng)仔細(xì)閱讀customSecurityPolicy方法并根據(jù)實(shí)際情況設(shè)置其屬性蜂莉。
這樣混卵,就能夠在AFNetWorking的基礎(chǔ)上使用HTTPS協(xié)議訪問特定服務(wù)器,但是不能信任根證書的CA文件蚁滋,因此這種方式存在風(fēng)險(xiǎn)赘淮,讀取pinnedCertificates中的證書數(shù)組的時(shí)候有可能失敗梢卸,如果證書不符合,certData就會(huì)為nil速梗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末襟齿,一起剝皮案震驚了整個(gè)濱河市猜欺,隨后出現(xiàn)的幾起案子拷窜,更是在濱河造成了極大的恐慌,老刑警劉巖赋荆,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窄潭,死亡現(xiàn)場(chǎng)離奇詭異酵颁,居然都是意外死亡月帝,警方通過查閱死者的電腦和手機(jī)幽污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門距误,熙熙樓的掌柜王于貴愁眉苦臉地迎上來准潭,“玉大人,你說我怎么就攤上這事则酝∪蚣” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵爽雄,是天一觀的道長(zhǎng)挚瘟。 經(jīng)常有香客問我饲梭,道長(zhǎng),這世上最難降的妖魔是什么订框? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任穿扳,我火速辦了婚禮国旷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘履羞。我一直安慰自己,他們只是感情好骨杂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布搓蚪。 她就那樣靜靜地躺著丁鹉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雳灾。 梳的紋絲不亂的頭發(fā)上冯凹,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天宇姚,我揣著相機(jī)與錄音,去河邊找鬼阱持。 笑死魔熏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的镶骗。 我是一名探鬼主播躲雅,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼吏夯,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼即横!你這毒婦竟也來了东囚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤桨嫁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后楣导,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畜挨,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巴元,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年逮刨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恢总。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡离熏,死狀恐怖戴涝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奸鸯,我是刑警寧澤可帽,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布映跟,位于F島的核電站,受9級(jí)特大地震影響球恤,放射性物質(zhì)發(fā)生泄漏荸镊。R本人自食惡果不足惜堪置,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一舀锨、第九天 我趴在偏房一處隱蔽的房頂上張望坎匿。 院中可真熱鬧拧额,春花似錦、人聲如沸侥锦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唠帝。三九已至玄柏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瀑晒,已是汗流浹背徘意。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工椎咧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蟋座。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像脚牍,于是被迫代替她去往敵國(guó)和親向臀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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

  • 原文地址 http://blog.csdn.net/u012409247/article/details/4985...
    0fbf551ff6fb閱讀 3,524評(píng)論 0 13
  • 快速適配直接看下面的示例代碼吧莫矗,概念有點(diǎn)多飒硅。。作谚。 自己客戶端生成證書放在服務(wù)器上三娩,可以自簽服務(wù)器必須ca簽署,服務(wù)...
    _YZG_閱讀 10,934評(píng)論 0 56
  • 一妹懒、作用 不使用SSL/TLS的HTTP通信雀监,就是不加密的通信眨唬。所有信息明文傳播会前,帶來了三大風(fēng)險(xiǎn)。 (1)竊聽風(fēng)險(xiǎn)...
    XLsn0w閱讀 10,553評(píng)論 2 44
  • 目錄 準(zhǔn)備 分析2.1. 三次握手2.2. 創(chuàng)建 HTTP 代理(非必要)2.3. TLS/SSL 握手2.4. ...
    RunAlgorithm閱讀 38,331評(píng)論 12 117
  • 1.OkHttp源碼解析(一):OKHttp初階2 OkHttp源碼解析(二):OkHttp連接的"前戲"——HT...
    隔壁老李頭閱讀 20,874評(píng)論 24 176