iOS 升級HTTPS通過ATS你所要知道的

由于蘋果規(guī)定2017年1月1日以后秃嗜,所有APP都要使用HTTPS進行網(wǎng)絡(luò)請求供汛,否則無法上架武氓,因此研究了一下在iOS中使用HTTPS請求的實現(xiàn)。網(wǎng)上搜索了一些比較有用資料,大家可以參考下


蘋果強制升級的HTTPS不僅僅是在接口HTTP上加個S那么簡單概疆,它所有滿足的是iOS9中新增App Transport Security(簡稱ATS)特性。

那滿足ATS我們需要做什么呢

- 1. 必須是蘋果信任的CA證書機構(gòu)頒發(fā)的證書
- 2. 后臺傳輸協(xié)議必須滿足: TLS1.2 (這很重要, 后面的自制證書滿足這個條件是前提)
- 3. 簽字算法只能是下面的一種:
屏幕快照 2016-12-08 下午2.12.46.png
-4. 證書必須使用SHA256或者更好的哈希算法進行簽名峰搪,要么是2048位或者更長的RSA密鑰岔冀,要么就是256位或更長的ECC密鑰。

目前有兩種升級到HTTPS的方法:

  • 一概耻、第三方認證的頒發(fā)CA證書(推薦)
  • 二使套、自己制作證書(這種不知道能不能滿足蘋果的審核)

一: 第三方認證的頒發(fā)CA證書

證書到底長什么樣子呢? 取個栗子:
大家請打開https://www.baidu.com
然后看到

百度證書分析

哪些證書機構(gòu)頒發(fā)的證書能用:蘋果官方信任證書

收費SSL證書: 網(wǎng)上百度一大把, 收費還挺貴的,自己可以多找?guī)讉€對比一下
免費SSL證書: 除了收費的CA證書機構(gòu), 你還可以去騰訊云申請免費的SSL證書, 教程免費在騰訊云申請SSL證書的方法

沃通(WoSign)免費的SSL證書最近被蘋果封殺了, 能不能用大家可以看一下蘋果的公告: 您的蘋果手機輕點“設(shè)置”>“通用”>“關(guān)于本機”>"證書信任設(shè)置">"進一步了解被信任的證書"去了解

檢測你的接口是否滿足蘋果的ATS要求, 有以下兩種方法:

1. 騰訊云提供的檢測頁面檢測
騰訊云的檢測頁面
2 終端輸入 nsurl --ats-diagnostics --verbose 你的接口地址

大家可以參考這篇文章,里面的說的很明白:
關(guān)于iOS9中的App Transport Security相關(guān)說明及適配(更新于2016.7.1)
里面會詳細說明你的證書哪點不符合ATS要求

自制證書

當然下面自己制作證書去實現(xiàn)HTTPS的,檢測不通過的,所以我覺得審核會被拒
這種方法配置好了, 在手機端就什么都不用配置就可以請求了

蘋果官方信任證書里說到有三種證書:

屏幕快照 2016-12-08 下午2.30.29.png

自制證書我覺得應該就是屬于第二種情況, 所以這種方法我也不知道能不能通過蘋果的審核, 只是提供一個方法給大家參考, 看到網(wǎng)上有人說可以,有人說不可以, 不到1月1號,自己沒試過都不敢說大話


這種方式拿到后臺的接口用谷歌瀏覽器打開跟百度的證書是有區(qū)別的

自己制作證書

很明顯沒有綠鎖, 當打開的時候會詢問是否連接這個不受信任的連接才會進一步打開, 下面就來一步步的實現(xiàn)(包括怎么制作證書)

iOS使用自簽名證書實現(xiàn)HTTPS請求
iOS Https協(xié)議 自簽證書訪問數(shù)據(jù)參考這個例子的時候,博主自帶的Demo AFN框架請求不了數(shù)據(jù), 我用了最新AFN版本的成功返回數(shù)據(jù)
還可以參考一下
iOS 10 適配 ATS app支持https通過App Store審核

我在利用原生的代碼測試時遇到的問題

    @interface ViewController () @end

    @implementation ViewController
    - (void)viewDidLoad {

    }

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
     {       NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
            NSURLSessionDataTask *task =  [session dataTaskWithURL:[NSURL URLWithString:@"[https://www.baidu.com](https://www.baidu.com/)"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {            
                    NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            }];


          [task resume];

    }

    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask   didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { 
          NSLog(@"接收到服務(wù)器響應");//注意:這里需要使用completionHandler回調(diào)告訴系統(tǒng)應該如何處理服務(wù)器返回的數(shù)據(jù)
          //默認是取消
          /**

 
            NSURLSessionResponseCancel = 0,            默認的處理方式,取消

 
            NSURLSessionResponseAllow = 1,             接收服務(wù)器返回的數(shù)據(jù)

 
            NSURLSessionResponseBecomeDownload = 2,    變成一個下載請求

 
             NSURLSessionResponseBecomeStream           變成一個流

 
            */


            completionHandler(NSURLSessionResponseAllow);

      }

    - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {

          NSLog(@"獲取到服務(wù)段數(shù)據(jù)");
          NSLog(@"%@",[self jsonToDictionary:data]);

    }

    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error {

          NSLog(@"請求完成%@", error);
    }

    - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {


           NSLog(@"證書認證");
          if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {
    
              do
              {
                SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
                NSCAssert(serverTrust != nil, @"serverTrust is nil");
                if(nil == serverTrust)
                      break; /* failed */
                /**
                  *  導入多張CA證書(Certification Authority咐蚯,支持SSL證書以及自簽名的CA)童漩,請?zhí)鎿Q掉你的證書名稱
                  */

        
                NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"cer"];//自簽名證書

        
                NSData* caCert = [NSData dataWithContentsOfFile:cerPath];

        
                NSCAssert(caCert != nil, @"caCert is nil");

                if(nil == caCert)
                      break; /* failed */

        
                SecCertificateRef caRef = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)caCert);

        
                NSCAssert(caRef != nil, @"caRef is nil");

        
                if(nil == caRef)
                  break; /* failed */

        
                //可以添加多張證書            
                NSArray *caArray = @[(__bridge id)(caRef)];
                NSCAssert(caArray != nil, @"caArray is nil");
                if(nil == caArray)
                    break; /* failed */

                //將讀取的證書設(shè)置為服務(wù)端幀數(shù)的根證書            
                OSStatus status = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)caArray);

        
                NSCAssert(errSecSuccess == status, @"SecTrustSetAnchorCertificates failed");

        
                if(!(errSecSuccess == status))
                  break; /* failed */

        
                SecTrustResultType result = -1;
        
                //通過本地導入的證書來驗證服務(wù)器的證書是否可信
                status = SecTrustEvaluate(serverTrust, &result);
                if(!(errSecSuccess == status))
                    break; /* failed */

        
                NSLog(@"stutas:%d",(int)status);
                NSLog(@"Result: %d", result);

        
                BOOL allowConnect = (result == kSecTrustResultUnspecified) || (result == kSecTrustResultProceed);
       
                if(allowConnect) {
                      NSLog(@"success");
                }else {
                  NSLog(@"error");
                 }           
                /* kSecTrustResultUnspecified and kSecTrustResultProceed are success */

                if(! allowConnect){
                    break; /* failed */
                }

#if 0

                /* Treat kSecTrustResultConfirm and kSecTrustResultRecoverableTrustFailure as success */

                /*   since the user will likely tap-through to see the dancing bunnies */

                if(result == kSecTrustResultDeny || result == kSecTrustResultFatalTrustFailure || result == kSecTrustResultOtherError)

                      break; /* failed to trust cert (good in this case) */

#endif

                // The only good exit point

                NSLog(@"信任該證書");

                NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

                completionHandler(NSURLSessionAuthChallengeUseCredential,credential);

                return [[challenge sender] useCredential: credential forAuthenticationChallenge: challenge];

          }
          while(0);

      }
      // Bad dog
       NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];

       completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,credential);

       return [[challenge sender] cancelAuthenticationChallenge: challenge];
  }

  - (NSDictionary *)jsonToDictionary:(NSData *)jsonData {

        NSError *jsonError;    
        NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&jsonError];

        return resultDic;
  }

  @end

下面說說我在配置自己制作證書過程中遇到的問題:

1.轉(zhuǎn)換證書: 把后臺給你的.crt證書轉(zhuǎn)化為.cer后綴

終端命令行openssl x509 -in 你的證書.crt -out 你的證書.cer -outform der

2.利用系統(tǒng)的方法來不到

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
        NSLog(@"證書認證");      
}

這個方法的時候, 是因為后臺的傳輸協(xié)議還沒升級到TLS1.2, 叫后臺升級后就可以來到驗證證書的這個方法了.

3.拖入證書讀取不出證書數(shù)據(jù)

參考: https的證書錯誤,錯誤碼-1012問題及解決方案

SDWebImage: 項目中大家用到AFN請求網(wǎng)絡(luò)數(shù)據(jù), 升級驗證SSL證書的方案相信你看完上面的參考文章已經(jīng)沒問題了, 我給出的代碼, 自定義網(wǎng)絡(luò)請求也沒問題了, 還有就是SDWebImage框架的請求HTTPS的圖片時,大家可以繞過證書驗證去加載圖片

    [imageView  sd_setImageWithURL:[NSURL URLWithString:urlString] placeholderImage:self.placeholder options:SDWebImageAllowInvalidSSLCertificates];

恩, 這就是這幾天升級HTTPS覺得有幫助的參考和總結(jié).希望幫到你春锋。

原文:http://www.cocoachina.com/ios/20161207/18308.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矫膨,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌侧馅,老刑警劉巖危尿,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異馁痴,居然都是意外死亡谊娇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門罗晕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來济欢,“玉大人,你說我怎么就攤上這事小渊》ㄈ欤” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵酬屉,是天一觀的道長半等。 經(jīng)常有香客問我,道長呐萨,這世上最難降的妖魔是什么杀饵? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮谬擦,結(jié)果婚禮上切距,老公的妹妹穿的比我還像新娘。我一直安慰自己怯屉,他們只是感情好蔚舀,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锨络,像睡著了一般赌躺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上羡儿,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天礼患,我揣著相機與錄音,去河邊找鬼掠归。 笑死缅叠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的虏冻。 我是一名探鬼主播肤粱,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼厨相!你這毒婦竟也來了领曼?” 一聲冷哼從身側(cè)響起鸥鹉,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎庶骄,沒想到半個月后毁渗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡单刁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年灸异,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羔飞。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡肺樟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出褥傍,到底是詐尸還是另有隱情儡嘶,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布恍风,位于F島的核電站,受9級特大地震影響誓篱,放射性物質(zhì)發(fā)生泄漏朋贬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一窜骄、第九天 我趴在偏房一處隱蔽的房頂上張望锦募。 院中可真熱鬧,春花似錦邻遏、人聲如沸糠亩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赎线。三九已至,卻和暖如春糊饱,著一層夾襖步出監(jiān)牢的瞬間垂寥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工另锋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留滞项,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓夭坪,卻偏偏與公主長得像文判,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子室梅,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

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