Alamofire和AFNetworking中https相關(guān)知識(shí)點(diǎn)

首先,配置https服務(wù)器需要一個(gè)證書(shū),這個(gè)證書(shū)可以從某些機(jī)構(gòu)獲得,也可以自己通過(guò)工具生成。

通過(guò)某些合法機(jī)構(gòu)生成的證書(shū)客戶端不需要進(jìn)行驗(yàn)證

這樣的請(qǐng)求不會(huì)觸發(fā)Apple的相關(guān)代理方法
(URLSession:task:didReceiveChallenge:completionHandler:)
所以無(wú)論是AFNetWorking還是Alamofire都不需要進(jìn)行任何處理,即可正常使用。

非合法機(jī)構(gòu)生成的證書(shū)或者自制證書(shū)

  • AFNetWorking

    AFSecurityPolicy分三種驗(yàn)證模式:

    1. AFSSLPinningModeNone:代表客戶端無(wú)條件地信任服務(wù)器端返回的證書(shū)。你不必將證書(shū)跟你的 APP 一起打包。
    2. AFSSLPinningModeCertificate:代表客戶端會(huì)將服務(wù)器端返回的證書(shū)和本地保存的證書(shū)中的【所有內(nèi)容】,全部進(jìn)行校驗(yàn);如果正確,才繼續(xù)進(jìn)行。
    3. AFSSLPinningModePublicKey:代表客戶端會(huì)將服務(wù)器端返回的證書(shū)與本地保存的證書(shū)中的【PublicKey部分】進(jìn)行校驗(yàn);如果正確,才繼續(xù)進(jìn)行。
    注: AFSSLPinningModeCertificate和AFSSLPinningModePublicKey的區(qū)別
    • AFSSLPinningModeCertificate 比較安全但也比較麻煩,它會(huì)比對(duì)你打包的證書(shū)跟服務(wù)器的證書(shū)是否一致。因?yàn)槟愕淖C書(shū)是跟 APP 一起打包的,這也就代表說(shuō)如果你的證書(shū)過(guò)期了或是變動(dòng)了,你就得出一版新的 APP 而且舊版 APP 的證書(shū)就失效了。你也可以在每次 APP 啟動(dòng)時(shí),就自動(dòng)連到某個(gè)服務(wù)器下載最新的證書(shū),不過(guò)此時(shí)這個(gè)下載連線就會(huì)是有風(fēng)險(xiǎn)的。

    • AFSSLPinningModePublicKey 則是只比對(duì)證書(shū)里的 public key,所以即使服務(wù)器證書(shū)有所變動(dòng),只要 public key 不變,就能通過(guò)驗(yàn)證。

    • 所以如果你能確保每個(gè)使用者總是使用最新版本的 APP(例如是公司企業(yè)內(nèi)部專用的),那就可以考慮AFSSLPinningModeCertificate,否則的話選擇 AFSSLPinningModePublicKey 是比較實(shí)際的作法。

    相關(guān)屬性解釋及代碼例子
    • 屬性解釋
     AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    
    /*
     allowInvalidCertificates 是否允許無(wú)效證書(shū)(也就是自建的證書(shū)),默認(rèn)為NO
     如果是需要驗(yàn)證自建證書(shū),需要設(shè)置為YES
     */
    securityPolicy.allowInvalidCertificates = YES;
    
    /*
     validatesDomainName 是否需要驗(yàn)證域名,默認(rèn)為YES。
     假如證書(shū)的域名與你請(qǐng)求的域名不一致,需把該項(xiàng)設(shè)置為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è)還是比較貴的。
     */
    securityPolicy.validatesDomainName = NO;
    
    /*
     validatesCertificateChain 是否驗(yàn)證整個(gè)證書(shū)鏈,默認(rèn)為YES
     設(shè)置為YES,會(huì)將服務(wù)器返回的Trust Object上的證書(shū)鏈與本地導(dǎo)入的證書(shū)進(jìn)行對(duì)比,這就意味著,假如你的證書(shū)鏈?zhǔn)沁@樣的:
     GeoTrust Global CA 
     Google Internet Authority G2
     *.google.com
     那么,除了導(dǎo)入*.google.com之外,還需要導(dǎo)入證書(shū)鏈上所有的CA證書(shū)(GeoTrust Global CA, Google Internet Authority G2);
     如是自建證書(shū)的時(shí)候,可以設(shè)置為YES,增強(qiáng)安全性;假如是信任的CA所簽發(fā)的證書(shū),則建議關(guān)閉該驗(yàn)證;
     */
    securityPolicy.validatesCertificateChain = NO;
    
    • 完整代碼
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    /*
    創(chuàng)建AFSecurityPolicy有兩種方式。
    第一種方式是讓AFN在Bundle里面自動(dòng)尋找并嘗試匹配。
    第二種方式是直接指定證書(shū)的位置
     */
    AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init]; 
    [securityPolicy setAllowInvalidCertificates:NO]; 
    [securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate]; 
    [securityPolicy setValidatesDomainName:YES];
    [securityPolicy setValidatesCertificateChain:NO]; 
    
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"name" ofType:@"cer"];
    NSData *certData  = [NSData dataWithContentsOfFile:cerPath];
    AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
    [securityPolicy setAllowInvalidCertificates:NO];
    [securityPolicy setPinnedCertificates:@[certData]];
    [securityPolicy setSSLPinningMode:AFSSLPinningModeCertificate];
    [securityPolicy setValidatesDomainName:YES];
    [securityPolicy setValidatesCertificateChain:NO];
    
    manager.securityPolicy = securityPolicy;
    
    
  • Alamofire

    ServerTrustPolicy分六種驗(yàn)證方式

    1.performDefaultEvaluation

    默認(rèn)的策略,只有合法證書(shū)才能通過(guò)驗(yàn)證

    2.performRevokedEvaluation

    對(duì)注銷證書(shū)做的一種額外設(shè)置,不是很明白這里,有興趣的朋友可以最近查一下。

    3.pinCertificates

    代表客戶端會(huì)將服務(wù)器端返回的證書(shū)和本地保存的證書(shū)中的【所有內(nèi)容】,全部進(jìn)行校驗(yàn);如果正確,才繼續(xù)進(jìn)行。

    4.pinPublicKeys

    代表客戶端會(huì)將服務(wù)器端返回的證書(shū)與本地保存的證書(shū)中的【PublicKey部分】進(jìn)行校驗(yàn);如果正確,才繼續(xù)進(jìn)行。

    5.disableEvaluation

    該選項(xiàng)下,驗(yàn)證一直都是通過(guò)的,也就是說(shuō)無(wú)條件信任

    6.customEvaluation

    自定義驗(yàn)證,需要返回一個(gè)布爾類型的結(jié)果

    注: pinPublicKeys和pinCertificates的區(qū)別可以參考上面AFN的介紹。
    相關(guān)參數(shù)的介紹
    • certificates
      證書(shū)文件。ServerTrustPolicy.certificates()方法會(huì)在bundle中自動(dòng)搜索證書(shū)相關(guān)文件的后綴文件。
    • validateCertificateChain
      是否驗(yàn)證證書(shū)鏈
    • validateHost
      是否驗(yàn)證域名地址。
    完整代碼

    這里最好是封裝一個(gè)SessionManger的單例進(jìn)行統(tǒng)一處理。Swift的https驗(yàn)證策略,支持一次對(duì)多個(gè)域名進(jìn)行設(shè)置。

    let serverTrustPolicies: [String: ServerTrustPolicy] = [
            "test.example.com": .pinCertificates(
                certificates: ServerTrustPolicy.certificates(),
                validateCertificateChain: true,
                validateHost: true
            ),
            "insecure.expired-apis.com": .disableEvaluation
        ]
    let manger = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies))
    
最后編輯于
?著作權(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),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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