Https 原理與驗(yàn)證過(guò)程
一、參考文章
HTTPS 基礎(chǔ)
OpenSSL 與 SSL 數(shù)字證書(shū)概念貼
iOS 中對(duì) HTTPS 證書(shū)鏈的驗(yàn)證
二、學(xué)習(xí)過(guò)程中的疑問(wèn)和解決
1. 證書(shū)的驗(yàn)證過(guò)程中自己計(jì)算加密摘要信息是怎么進(jìn)行的。
剛開(kāi)始接觸時(shí)對(duì)證書(shū)的驗(yàn)證過(guò)程,主要的困惑在于證書(shū)自己怎么計(jì)算自己的摘要從而與上一級(jí)證書(shū)解密出來(lái)的摘要進(jìn)行對(duì)比。后面了解這與證書(shū)的生成過(guò)程有關(guān)。摘要里面的信息是公開(kāi)的,而且加密算法也是公開(kāi)的,所以每個(gè)證書(shū)都能自己計(jì)算出自己加密 后的摘要信息。
摘要與數(shù)字簽名生成:
關(guān)于自建證書(shū)與申請(qǐng)的證書(shū)驗(yàn)證時(shí)的區(qū)別
- 申請(qǐng)的證書(shū):申請(qǐng)的證書(shū)不用在項(xiàng)目中導(dǎo)入cer文件,如果是用AFNetworking 進(jìn)行網(wǎng)絡(luò)請(qǐng)求的話,只需要進(jìn)行下面兩步:
<1> 生成一個(gè)policy:
- (AFSecurityPolicy *)customSecurityPolicy
{
//先導(dǎo)入證書(shū),找到證書(shū)的路徑
// NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"2_eoojia" ofType:@"cer"];
// NSData *certData = [NSData dataWithContentsOfFile:cerPath];
//AFSSLPinningModeCertificate 使用證書(shū)驗(yàn)證模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
//allowInvalidCertificates 是否允許無(wú)效證書(shū)(也就是自建的證書(shū)),默認(rèn)為NO
//如果是需要驗(yàn)證自建證書(shū),需要設(shè)置為YES
securityPolicy.allowInvalidCertificates = NO;
//validatesDomainName 是否需要驗(yàn)證域名,默認(rèn)為YES;
//假如證書(shū)的域名與你請(qǐng)求的域名不一致,需把該項(xiàng)設(shè)置為NO;如設(shè)成NO的話,即服務(wù)器使用其他可信任機(jī)構(gòu)頒發(fā)的證書(shū),也可以建立連接,這個(gè)非常危險(xiǎn),建議打開(kāi)。
//置為NO,主要用于這種情況:客戶端請(qǐng)求的是子域名,而證書(shū)上的是另外一個(gè)域名。因?yàn)镾SL證書(shū)上的域名是獨(dú)立的,假如證書(shū)上注冊(cè)的域名是www.google.com,那么mail.google.com是無(wú)法驗(yàn)證通過(guò)的;當(dāng)然,有錢(qián)可以注冊(cè)通配符的域名*.google.com,但這個(gè)還是比較貴的。
//如置為NO,建議自己添加對(duì)應(yīng)域名的校驗(yàn)邏輯。
securityPolicy.validatesDomainName = YES;
// securityPolicy.validatesCertificateChain = NO;
// NSSet *set = [[NSSet alloc] initWithObjects:certData, nil];
// NSSet *set = [AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]];
// securityPolicy.pinnedCertificates = set;
return securityPolicy;
}
<2> 設(shè)置[sessionManager setSecurityPolicy:[self customSecurityPolicy]];
即可,不需要導(dǎo)入證書(shū),因?yàn)槟闵暾?qǐng)的證書(shū)已經(jīng)在信任列表里面了,系統(tǒng)會(huì)自動(dòng)進(jìn)行驗(yàn)證,就像瀏覽器做的那樣。
- 自建證書(shū)的驗(yàn)證
方法同上,但是要導(dǎo)入證書(shū)鏈,然后AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];改為AFSSLPinningModeCertificate,然后加入證書(shū)即可。(這只是猜想沒(méi)有經(jīng)過(guò)驗(yàn)證)
三、需要注意的問(wèn)題
1. 驗(yàn)證證書(shū)有效性的方法
驗(yàn)證會(huì)從最底的證書(shū)開(kāi)始:假設(shè)有三級(jí)證書(shū),分別為A,B,C;
A: 根證書(shū),一般是被加到客戶端的信任列表里面的。
B: 二級(jí)證書(shū)
C: 客戶端證書(shū)
驗(yàn)證步驟:
- 用B證書(shū)的pubKey(公鑰)來(lái)解密C的簽名信息,得到C的加密后的摘要。
- C證書(shū)通過(guò)證書(shū)中標(biāo)明的加密算法來(lái)計(jì)算出加密后摘要。
- 比對(duì)這兩份摘要,如果一致,表明B信任C。
- 用同樣的方法,判斷A是否信任B
- 因?yàn)锳是根證書(shū),所以這時(shí)不會(huì)再用上面的方法,而是用客戶端信任證書(shū)列表里面存儲(chǔ)的證書(shū)與A 進(jìn)行比對(duì),如果有一致的,說(shuō)明這個(gè)證書(shū)鏈?zhǔn)强尚诺摹?/li>
- 完成證書(shū)的驗(yàn)證。