為您解碼網(wǎng)站建設(shè)的點(diǎn)點(diǎn)滴滴
發(fā)表日期:2016-12 文章編輯:小燈 瀏覽次數(shù):2254
由于蘋(píng)果規(guī)定2017年1月1日以后,所有APP都要使用HTTPS進(jìn)行網(wǎng)絡(luò)請(qǐng)求,否則無(wú)法上架,因此研究了一下在iOS中使用HTTPS請(qǐng)求的實(shí)現(xiàn)。網(wǎng)上搜索了一些比較有用資料,大家可以參考下
蘋(píng)果強(qiáng)制升級(jí)的HTTPS不僅僅是在接口HTTP上加個(gè)S那么簡(jiǎn)單:
它所有滿(mǎn)足的是iOS9中新增App Transport Security(簡(jiǎn)稱(chēng)ATS)特性:
那滿(mǎn)足ATS我們需要做什么呢
1.必須是蘋(píng)果信任的CA證書(shū)機(jī)構(gòu)頒發(fā)的證書(shū)
2.后臺(tái)傳輸協(xié)議必須滿(mǎn)足: TLS1.2 (這很重要, 后面的自制證書(shū)滿(mǎn)足這個(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.證書(shū)必須使用SHA256或者更好的哈希算法進(jìn)行簽名,要么是2048位或者更長(zhǎng)的RSA密鑰,要么就是256位或更長(zhǎng)的ECC密鑰。
目前有兩種升級(jí)到HTTPS得方法:
1.第三方認(rèn)證的頒發(fā)CA證書(shū)(推薦)
2.自己制作證書(shū)(這種不知道能不能滿(mǎn)足蘋(píng)果的審核)
一: 第三方認(rèn)證的頒發(fā)CA證書(shū)
證書(shū)到底長(zhǎng)什么樣子呢? 取個(gè)栗子:
大家請(qǐng)打開(kāi)https://www.baidu.com
然后看到
百度的證書(shū)分析
那些證書(shū)機(jī)構(gòu)頒發(fā)的證書(shū)能用:蘋(píng)果官方信任證書(shū)
收費(fèi)SSL證書(shū): 網(wǎng)上百度一大把, 收費(fèi)還挺貴的,自己可以多找?guī)讉€(gè)對(duì)比一下
免費(fèi)SSL證書(shū): 除了收費(fèi)的CA證書(shū)機(jī)構(gòu), 你還可以去騰訊云申請(qǐng)免費(fèi)的SSL證書(shū), 教程免費(fèi)在騰訊云申請(qǐng)SSL證書(shū)的方法
沃通(WoSign)免費(fèi)的SSL證書(shū)最近被蘋(píng)果封殺了, 能不能用大家可以看一下蘋(píng)果的公告: 您的蘋(píng)果手機(jī)輕點(diǎn)“設(shè)置”>“通用”>“關(guān)于本機(jī)”>"證書(shū)信任設(shè)置">"進(jìn)一步了解被信任的證書(shū)"去了解
檢測(cè)你的接口是否滿(mǎn)足蘋(píng)果的ATS要求, 有以下兩種方法:
1.騰訊云提供的檢測(cè)頁(yè)面檢測(cè)
騰訊云的檢測(cè)頁(yè)面
2 終端輸入 nsurl --ats-diagnostics --verbose 你的接口地址
大家可以參考這篇文章,里面的說(shuō)的很明白:
關(guān)于iOS9中的App Transport Security相關(guān)說(shuō)明及適配(更新于2016.7.1)
里面會(huì)詳細(xì)說(shuō)明你的證書(shū)哪點(diǎn)不符合ATS要求
當(dāng)然下面自己制作證書(shū)去實(shí)現(xiàn)HTTPS的,檢測(cè)不通過(guò)的,所以我覺(jué)得審核會(huì)被拒
這種方法配置好了, 在手機(jī)端就什么都不用配置就可以請(qǐng)求了
二: 自己制作證書(shū)
蘋(píng)果官方信任證書(shū)里說(shuō)到有三種證書(shū):
1
2
3
1?可信的根證書(shū)用于建立信任鏈,以驗(yàn)證由可信的根簽署的其他證書(shū),例如,與?Web?服務(wù)器建立安全連接。當(dāng)?IT?管理員創(chuàng)建?iPhone、iPad?或?iPod?touch?的配置描述文件時(shí),無(wú)需提供這些可信的根證書(shū)。
2?始終詢(xún)問(wèn)的證書(shū)不受信任,但不受阻止。使用其中一個(gè)證書(shū)時(shí),系統(tǒng)將提示您選擇是否信任該證書(shū)。
3?已阻止的證書(shū)視為被盜用,將不再受信任。
自制證書(shū)我覺(jué)得應(yīng)該就是屬于第二種情況, 所以這種方法我也不知道能不能通過(guò)蘋(píng)果的審核, 只是提供一個(gè)方法給大家參考, 看到網(wǎng)上有人說(shuō)可以,有人說(shuō)不可以, 不到1月1號(hào),自己沒(méi)試過(guò)都不敢說(shuō)大話(huà)
這種方式拿到后臺(tái)的接口用谷歌瀏覽器打開(kāi)跟百度的證書(shū)是有區(qū)別的
自己制作證書(shū)
很明顯沒(méi)有綠鎖, 當(dāng)打開(kāi)的時(shí)候會(huì)詢(xún)問(wèn)是否連接這個(gè)不受信任的連接才會(huì)進(jìn)一步打開(kāi), 下面就來(lái)一步步的實(shí)現(xiàn)(包括怎么制作證書(shū))
iOS使用自簽名證書(shū)實(shí)現(xiàn)HTTPS請(qǐng)求
iOS Https協(xié)議 自簽證書(shū)訪(fǎng)問(wèn)數(shù)據(jù)參考這個(gè)例子的時(shí)候,博主自帶的Demo AFN框架請(qǐng)求不了數(shù)據(jù), 我用了最新AFN版本的成功返回?cái)?shù)據(jù)
還可以參考一下
iOS 10 適配 ATS app支持https通過(guò)App Store審核
我在利用原生的代碼測(cè)試時(shí)遇到的問(wèn)題
@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(@"證書(shū)認(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證書(shū)(Certification?Authority,支持SSL證書(shū)以及自簽名的CA),請(qǐng)?zhí)鎿Q掉你的證書(shū)名稱(chēng)
*/
NSString?*cerPath?=?[[NSBundle?mainBundle]?pathForResource:@"ca"ofType:@"cer"];//自簽名證書(shū)
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?*/
//可以添加多張證書(shū)
NSArray?*caArray?=?@[(__bridge?id)(caRef)];
NSCAssert(caArray?!=?nil,?@"caArray?is?nil");
if(nil?==?caArray)
break;?/*?failed?*/
//將讀取的證書(shū)設(shè)置為服務(wù)端幀數(shù)的根證書(shū)
OSStatus?status?=?SecTrustSetAnchorCertificates(serverTrust,?(__bridge?CFArrayRef)caArray);
NSCAssert(errSecSuccess?==?status,?@"SecTrustSetAnchorCertificates?failed");
if(!(errSecSuccess?==?status))
break;?/*?failed?*/
SecTrustResultType?result?=?-1;
//通過(guò)本地導(dǎo)入的證書(shū)來(lái)驗(yàn)證服務(wù)器的證書(shū)是否可信
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(@"信任該證書(shū)");
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
下面說(shuō)說(shuō)我在配置自己制作證書(shū)過(guò)程中遇到的問(wèn)題:
1.轉(zhuǎn)換證書(shū): 把后臺(tái)給你的.crt證書(shū)轉(zhuǎn)化為.cer后綴
終端命令行openssl x509 -in 你的證書(shū).crt -out 你的證書(shū).cer -outform der
2.利用系統(tǒng)的方法來(lái)不到
1
2
3
4
-?(void)URLSession:(NSURLSession?*)session?didReceiveChallenge:(NSURLAuthenticationChallenge?*)challenge
completionHandler:(void?(^)(NSURLSessionAuthChallengeDisposition?disposition,?NSURLCredential?*?_Nullable?credential))completionHandler?{
NSLog(@"證書(shū)認(rèn)證");
}
這個(gè)方法的時(shí)候, 是因?yàn)楹笈_(tái)的傳輸協(xié)議還沒(méi)升級(jí)到TLS1.2, 叫后臺(tái)升級(jí)后就可以來(lái)到驗(yàn)證證書(shū)的這個(gè)方法了.
3.拖入證書(shū)讀取不出證書(shū)數(shù)據(jù)
參考:https的證書(shū)錯(cuò)誤,錯(cuò)誤碼-1012問(wèn)題及解決方案
SDWebImage: 項(xiàng)目中大家用到AFN請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù), 升級(jí)驗(yàn)證SSL證書(shū)的方案相信你看完上面的參考文章已經(jīng)沒(méi)問(wèn)題了, 我給出的代碼, 自定義網(wǎng)絡(luò)請(qǐng)求也沒(méi)問(wèn)題了, 還有就是SDWebImage框架的請(qǐng)求HTTPS的圖片時(shí),大家可以繞過(guò)證書(shū)驗(yàn)證去加載圖片
1
[imageView?sd_setImageWithURL:[NSURL?URLWithString:urlString]?placeholderImage:self.placeholder?options:SDWebImageAllowInvalidSSLCertificates];
希望幫到你。
日期:2018-04 瀏覽次數(shù):6808
日期:2017-02 瀏覽次數(shù):3489
日期:2017-09 瀏覽次數(shù):3716
日期:2017-12 瀏覽次數(shù):3575
日期:2018-12 瀏覽次數(shù):4879
日期:2016-12 瀏覽次數(shù):4632
日期:2017-07 瀏覽次數(shù):13688
日期:2017-12 瀏覽次數(shù):3560
日期:2018-06 瀏覽次數(shù):4310
日期:2018-05 瀏覽次數(shù):4494
日期:2017-12 瀏覽次數(shù):3605
日期:2017-06 瀏覽次數(shù):4027
日期:2018-01 瀏覽次數(shù):3995
日期:2016-12 瀏覽次數(shù):3952
日期:2018-08 瀏覽次數(shù):4467
日期:2017-12 瀏覽次數(shù):3771
日期:2016-09 瀏覽次數(shù):6523
日期:2018-07 瀏覽次數(shù):3254
日期:2016-12 瀏覽次數(shù):3274
日期:2018-10 瀏覽次數(shù):3424
日期:2018-10 瀏覽次數(shù):3529
日期:2018-09 瀏覽次數(shù):3617
日期:2018-02 瀏覽次數(shù):3642
日期:2015-05 瀏覽次數(shù):3565
日期:2018-09 瀏覽次數(shù):3355
日期:2018-06 瀏覽次數(shù):3475
日期:2017-02 瀏覽次數(shù):3917
日期:2018-02 瀏覽次數(shù):4375
日期:2018-02 瀏覽次數(shù):4240
日期:2016-12 瀏覽次數(shù):3618
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.