http升級(jí)至https

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

蘋果強(qiáng)制升級(jí)的HTTPS不僅僅是在接口HTTP上加個(gè)S那么簡(jiǎn)單:

它所有滿足的是iOS9中新增App Transport Security(簡(jiǎn)稱ATS)特性:

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

1.必須是蘋果信任的CA證書機(jī)構(gòu)頒發(fā)的證書

2.后臺(tái)傳輸協(xié)議必須滿足: TLS1.2 (這很重要, 后面的自制證書滿足這個(gè)條件是前提)

3.簽字算法只能是下面的一種:

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384

TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA

TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256

TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

4.證書必須使用SHA256或者更好的哈希算法進(jìn)行簽名,要么是2048位或者更長(zhǎng)的RSA密鑰,要么就是256位或更長(zhǎng)的ECC密鑰。

目前有兩種升級(jí)到HTTPS得方法:

1.第三方認(rèn)證的頒發(fā)CA證書(推薦)

2.自己制作證書(這種不知道能不能滿足蘋果的審核)

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

證書到底長(zhǎng)什么樣子呢? 取個(gè)栗子:

大家請(qǐng)打開https://www.baidu.com

然后看到

百度的證書分析

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

收費(fèi)SSL證書: 網(wǎng)上百度一大把, 收費(fèi)還挺貴的,自己可以多找?guī)讉€(gè)對(duì)比一下

免費(fèi)SSL證書: 除了收費(fèi)的CA證書機(jī)構(gòu), 你還可以去騰訊云申請(qǐng)免費(fèi)的SSL證書, 教程免費(fèi)在騰訊云申請(qǐng)SSL證書的方法

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

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

1.騰訊云提供的檢測(cè)頁(yè)面檢測(cè)

騰訊云的檢測(cè)頁(yè)面

2 終端輸入 nsurl --ats-diagnostics --verbose 你的接口地址

大家可以參考這篇文章,里面的說的很明白:

關(guān)于iOS9中的App Transport Security相關(guān)說明及適配(更新于2016.7.1)

里面會(huì)詳細(xì)說明你的證書哪點(diǎn)不符合ATS要求

當(dāng)然下面自己制作證書去實(shí)現(xiàn)HTTPS的,檢測(cè)不通過的,所以我覺得審核會(huì)被拒

這種方法配置好了, 在手機(jī)端就什么都不用配置就可以請(qǐng)求了

二: 自己制作證書

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

1

2

3

1?可信的根證書用于建立信任鏈,以驗(yàn)證由可信的根簽署的其他證書,例如,與?Web?服務(wù)器建立安全連接。當(dāng)?IT?管理員創(chuàng)建?iPhone、iPad?或?iPod?touch?的配置描述文件時(shí),無需提供這些可信的根證書。

2?始終詢問的證書不受信任,但不受阻止。使用其中一個(gè)證書時(shí),系統(tǒng)將提示您選擇是否信任該證書。

3?已阻止的證書視為被盜用,將不再受信任。

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

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

自己制作證書

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

iOS使用自簽名證書實(shí)現(xiàn)HTTPS請(qǐng)求

iOS Https協(xié)議 自簽證書訪問數(shù)據(jù)參考這個(gè)例子的時(shí)候,博主自帶的Demo AFN框架請(qǐng)求不了數(shù)據(jù), 我用了最新AFN版本的成功返回?cái)?shù)據(jù)

還可以參考一下

iOS 10 適配 ATS app支持https通過App Store審核

我在利用原生的代碼測(cè)試時(shí)遇到的問題

@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"]?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ù)器響應(yīng)");

//注意:這里需要使用completionHandler回調(diào)告訴系統(tǒng)應(yīng)該如何處理服務(wù)器返回的數(shù)據(jù)

//默認(rèn)是取消

/**

NSURLSessionResponseCancel?=?0,????????????默認(rèn)的處理方式,取消

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

NSURLSessionResponseBecomeDownload?=?2,????變成一個(gè)下載請(qǐng)求

NSURLSessionResponseBecomeStream???????????變成一個(gè)流

*/

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(@"請(qǐng)求完成%@",?error);

}

-?(void)URLSession:(NSURLSession?*)session?didReceiveChallenge:(NSURLAuthenticationChallenge?*)challenge

completionHandler:(void?(^)(NSURLSessionAuthChallengeDisposition?disposition,?NSURLCredential?*?_Nullable?credential))completionHandler?{

NSLog(@"證書認(rèn)證");

if([[[challenge?protectionSpace]?authenticationMethod]?isEqualToString:?NSURLAuthenticationMethodServerTrust])?{

do

{

SecTrustRef?serverTrust?=?[[challenge?protectionSpace]?serverTrust];

NSCAssert(serverTrust?!=?nil,?@"serverTrust?is?nil");

if(nil?==?serverTrust)

break;?/*?failed?*/

/**

*??導(dǎo)入多張CA證書(Certification?Authority,支持SSL證書以及自簽名的CA),請(qǐng)?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;

//通過本地導(dǎo)入的證書來驗(yàn)證服務(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];

returnresultDic;

}

@end

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

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

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

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

1

2

3

4

-?(void)URLSession:(NSURLSession?*)session?didReceiveChallenge:(NSURLAuthenticationChallenge?*)challenge

completionHandler:(void?(^)(NSURLSessionAuthChallengeDisposition?disposition,?NSURLCredential?*?_Nullable?credential))completionHandler?{

NSLog(@"證書認(rèn)證");

}

這個(gè)方法的時(shí)候, 是因?yàn)楹笈_(tái)的傳輸協(xié)議還沒升級(jí)到TLS1.2, 叫后臺(tái)升級(jí)后就可以來到驗(yàn)證證書的這個(gè)方法了.

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

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

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

1

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

希望幫到你。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 由于蘋果規(guī)定2017年1月1日以后,所有APP都要使用HTTPS進(jìn)行網(wǎng)絡(luò)請(qǐng)求,否則無法上架,因此研究了一下在iOS...
    等這姑娘老在我心里閱讀 1,509評(píng)論 0 10
  • iOS 10 適配 ATS 一. HTTPS其實(shí)HTTPS從最終的數(shù)據(jù)解析的角度,與HTTP沒有任何的區(qū)別,HTT...
    lanceChris閱讀 1,071評(píng)論 0 0
  • iOS 10 適配 ATS 一. HTTPS 其實(shí)HTTPS從最終的數(shù)據(jù)解析的角度,與HTTP沒有任何的區(qū)別,HT...
    made_China閱讀 1,733評(píng)論 0 12
  • 寫作是我一直想做,但一直沒實(shí)現(xiàn)的事,總感覺心靜不下來,無法把內(nèi)心的東西寫出來。 記得上學(xué)時(shí),我習(xí)慣寫日記,從初中開...
    我若盛開清風(fēng)自來閱讀 205評(píng)論 3 6
  • 總是一個(gè)人做在窗前,看著32層的夜景,一根接一根的抽著。 曾經(jīng)我是多么討厭那些抽煙的人,覺得他們都有病,現(xiàn)在才發(fā)現(xiàn)...
    喵小七先森閱讀 253評(píng)論 0 1