請(qǐng)求https The certificate for this server is invalid -1202

先開心一下

情況說明:用post方法加載一個(gè)h5頁面,請(qǐng)求的url為https的,web服務(wù)器掛的證書是自建證書,報(bào)錯(cuò):


2018-03-17 11:50:09.341674+0800 ICBCPayDemo[2216:1514635] TIC SSL Trust Error [7:0x1c01729c0]: 3:0


2018-03-17 11:50:09.542477+0800 ICBCPayDemo[2216:1514635] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)


2018-03-17 11:50:09.543400+0800 ICBCPayDemo[2216:1514635] Task .<0> HTTP load failed (error code: -1202 [3:-9813])


2018-03-17 11:50:09.545843+0800 ICBCPayDemo[2216:1514343] NSURLConnection finished with error - code -1202


2018-03-17 11:50:09.554470+0800 ICBCPayDemo[2216:1514273] didFailLoadWithError:Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “ebankp-pay-agn.sdc.cs.icbc” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, NSErrorPeerCertificateChainKey=


幾種解決方式:

第一種:使用私有API,擴(kuò)展NSURLRequest

? ??????只要填上這些就直接能用

第二種:生成.cer格式的證書,添加到工程中(未親測(cè))

? ? ? ? 方法來源:http://www.jb51.net/article/132096.html

? ??????1. 雙擊證書,這時(shí)證書已經(jīng)添加到了鑰匙串中

? ??????2. 將cer 文件拖入工程中

? ??????3. 如果使用的是AFNetwotking 的話,在代碼中添加以下代碼

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

?//證書

?AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

?manager.securityPolicy = securityPolicy;

// 2.設(shè)置證書模式

?NSString * cerPath = [[NSBundle mainBundle] pathForResource:@"tomcat" ofType:@"cer"]; //tomcat是cer文件的名稱

?NSData * cerData = [NSData dataWithContentsOfFile:cerPath];

?manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:cerData, nil]];

?// 客戶端是否信任非法證書

?manager.securityPolicy.allowInvalidCertificates = YES;

?// 是否在證書域字段中驗(yàn)證域名

?[manager.securityPolicy setValidatesDomainName:NO];

????????但這個(gè)cer文件不知道能不能導(dǎo)出來,沒找到mac版chrome的導(dǎo)出方法,windows導(dǎo)出方式看:https://wdd.js.org/export-https-certificate-in-browser.html

? ? ? ? 這個(gè)導(dǎo)出方式看起來靠譜點(diǎn)兒,但也沒試,感覺應(yīng)該由環(huán)境配置人員去搞:http://www.cocoachina.com/ios/20160928/17663.html

第三:

自建證書,將證書導(dǎo)入工程(其實(shí)沒有自建證書怎么導(dǎo)入工程啊哈)

-?(void)viewDidLoad?{

????[superviewDidLoad];

????//導(dǎo)入客戶端證書

????NSString?*cerPath?=?[[NSBundle?mainBundle]?pathForResource:@"ca"ofType:@"cer"];

????NSData?*data?=?[NSData?dataWithContentsOfFile:cerPath];

????SecCertificateRef?certificate?=?SecCertificateCreateWithData(NULL,?(__bridge?CFDataRef)?data);

????self.trustedCerArr?=?@[(__bridge_transfer?id)certificate];

????//發(fā)送請(qǐng)求

NSURL?*testURL?=?[NSURL?URLWithString:@"https://casetree.cn/web/test/demo.php"];

????NSURLSession?*session?=?[NSURLSession?sessionWithConfiguration:[NSURLSessionConfiguration?defaultSessionConfiguration]?delegate:self?delegateQueue:[NSOperationQueue?mainQueue]];

????NSURLSessionDataTask?*task?=?[session?dataTaskWithRequest:[NSURLRequest?requestWithURL:testURL]];

????[task?resume];

????//?Do?any?additional?setup?after?loading?the?view,?typically?from?a?nib.

}

#pragma?mark?-?NSURLSessionDelegate

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

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

????OSStatus?err;

????NSURLSessionAuthChallengeDisposition?disposition?=?NSURLSessionAuthChallengePerformDefaultHandling;

????SecTrustResultType??trustResult?=?kSecTrustResultInvalid;

????NSURLCredential?*credential?=?nil;

????//獲取服務(wù)器的trust?object

????SecTrustRef?serverTrust?=?challenge.protectionSpace.serverTrust;

????//將讀取的證書設(shè)置為serverTrust的根證書

????err?=?SecTrustSetAnchorCertificates(serverTrust,?(__bridge?CFArrayRef)self.trustedCerArr);

????if(err?==?noErr){

????????//通過本地導(dǎo)入的證書來驗(yàn)證服務(wù)器的證書是否可信,如果將SecTrustSetAnchorCertificatesOnly設(shè)置為NO,則只要通過本地或者系統(tǒng)證書鏈任何一方認(rèn)證就行

????????err?=?SecTrustEvaluate(serverTrust,?&trustResult);

????}

????if(err?==?errSecSuccess?&&?(trustResult?==?kSecTrustResultProceed?||?trustResult?==?kSecTrustResultUnspecified)){

????????//認(rèn)證成功,則創(chuàng)建一個(gè)憑證返回給服務(wù)器

????????disposition?=?NSURLSessionAuthChallengeUseCredential;

????????credential?=?[NSURLCredential?credentialForTrust:serverTrust];

????}

????else{

????????disposition?=?NSURLSessionAuthChallengeCancelAuthenticationChallenge;

????}

????//回調(diào)憑證,傳遞給服務(wù)器

????if(completionHandler){

????????completionHandler(disposition,?credential);

????}

}

不能解決問題的方式:

第一:

寫進(jìn)plist還是報(bào)錯(cuò)

相關(guān)知識(shí)點(diǎ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ù)

3. 加密通信協(xié)議


驗(yàn)證證書的API

相關(guān)的Api在Security Framework中,驗(yàn)證流程如下:

1). 第一步,先獲取需要驗(yàn)證的信任對(duì)象(Trust Object)。這個(gè)Trust Object在不同的應(yīng)用場(chǎng)景下獲取的方式都不一樣,對(duì)于NSURLConnection來說,是從delegate方法-connection:willSendRequestForAuthenticationChallenge:回調(diào)回來的參數(shù)challenge中獲取([challenge.protectionSpace serverTrust])。

2). 使用系統(tǒng)默認(rèn)驗(yàn)證方式驗(yàn)證Trust Object。SecTrustEvaluate會(huì)根據(jù)Trust Object的驗(yàn)證策略,一級(jí)一級(jí)往上,驗(yàn)證證書鏈上每一級(jí)數(shù)字簽名的有效性(上一部分有講解),從而評(píng)估證書的有效性。

3). 如第二步驗(yàn)證通過了,一般的安全要求下,就可以直接驗(yàn)證通過,進(jìn)入到下一步:使用Trust Object生成一份憑證([NSURLCredential credentialForTrust:serverTrust]),傳入challenge的sender中([challenge.sender useCredential:cred forAuthenticationChallenge:challenge])處理,建立連接。

4). 假如有更強(qiáng)的安全要求,可以繼續(xù)對(duì)Trust Object進(jìn)行更嚴(yán)格的驗(yàn)證。常用的方式是在本地導(dǎo)入證書,驗(yàn)證Trust Object與導(dǎo)入的證書是否匹配。更多的方法可以查看Enforcing Stricter Server Trust Evaluation,這一部分在講解AFNetworking源碼中會(huì)講解到。

5). 假如驗(yàn)證失敗,取消此次Challenge-Response Authentication驗(yàn)證流程,拒絕連接請(qǐng)求。

ps: 假如是自建證書的,則會(huì)跳過第二步,使用第三部進(jìn)行驗(yàn)證,因?yàn)樽越ㄗC書的根CA的數(shù)字簽名未在操作系統(tǒng)的信任列表中。


搭建完HTTPS服務(wù)器之后,可以使用nscurl命令來進(jìn)行檢測(cè),查看建立的HTTPS服務(wù)器是否能通過ATS特性。

1nscurl?--ats-diagnostics?--verbose?https://casetree.cn


那么,如何本地導(dǎo)入證書進(jìn)行驗(yàn)證呢??

在這里先提一下,由于iOS客戶端支持的證書是DER格式的,我們需要?jiǎng)?chuàng)建客戶端證書。創(chuàng)建客戶端證書,直接將服務(wù)端的CA根證書導(dǎo)出成DER格式就行。

1openssl??x509??-inform?PEM??-outform?DER?-inca.crt?-out?ca.cer

另外也有說:把服務(wù)器給你的自簽證的證書放入bundle一般是.cer文件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容