項(xiàng)目剖析04-swift 網(wǎng)絡(luò)請(qǐng)求Moya+Alamofire(HTTPS)證書(shū)驗(yàn)證

SSL證書(shū)驗(yàn)證

?一種加強(qiáng)App 和 Server 間通訊安全的方法。主要目標(biāo)是確保 App 僅與預(yù)先驗(yàn)證的 Server 建立安全連接,防止中間人攻擊(Man-in-the-Middle,MitM)等安全風(fēng)險(xiǎn)。一般常用的有兩種方式進(jìn)行驗(yàn)證,Certificate Pinning和Public Key Pinning。

Alamofire5.0 以后將證書(shū)驗(yàn)證類放于ServerTrustEvaluation這個(gè)類里面。一共有6種驗(yàn)證策略:

  1. DefaultTrustEvaluator - (默認(rèn)驗(yàn)證策略)只要是合法證書(shū)就能通過(guò)驗(yàn)證。
  2. RevocationTrustEvaluator(驗(yàn)證注銷策略)對(duì)注銷證書(shū)做的一種額外設(shè)置,Alamofire從iOS10.1才開(kāi)始支持吊銷證書(shū)的策略。
  3. PinnedCertificatesTrustEvaluator(證書(shū)驗(yàn)證策略)app端會(huì)對(duì)服務(wù)器端返回的證書(shū)和本地保存的證書(shū)中的全部?jī)?nèi)容進(jìn)行校驗(yàn)需要全部正確,此驗(yàn)證策略還可以接受自簽名證書(shū),安全性相對(duì)較高,此方法較為固定,如果 Server 更新證書(shū),App 需要定期更新并重新上架。
  4. PublicKeysTrustEvaluator(公鑰驗(yàn)證策略)app端只會(huì)對(duì)服務(wù)器返回的證書(shū)和本地保存的證書(shū)中的 PublicKey(公鑰)進(jìn)行校驗(yàn),所以當(dāng)證書(shū)需要更新時(shí),只需確保公鑰保持不變,不需要更新App。
  5. CompositeTrustEvaluator(自定義組合驗(yàn)證策略)以上多種策略組合一起,只有在所有數(shù)組中值都成功時(shí)才成功。
  6. DisabledTrustEvalutor(不驗(yàn)驗(yàn)證策略)無(wú)條件信任,所有都可以通過(guò)驗(yàn)證。正式環(huán)境不建議用此策略,多用于測(cè)試。

我們用的是PublicKeysTrustEvaluator(公鑰驗(yàn)證策略)


1.后臺(tái)提供證書(shū),將正式放在項(xiàng)目目錄中。

本地證書(shū)存放

2.獲取本地證書(shū),提取證書(shū)的公鑰(獲取公鑰key數(shù)組)。證書(shū)后綴名一般有:.cer、.crt、.der等,我項(xiàng)目中用的cer,證書(shū)鏈必須包含一個(gè)固定的公鑰。

struct WTCertificates {
    static let rootCA = WTCertificates.certificate( )
    static func certificate() -> [SecKey] {
        var publicKeyArray:[SecKey] = []
        for resource in ["xxx", "xxxx", "xxxxx"] {// 本地證書(shū)名稱
            if let filePath = Bundle.main.path(forResource: resource, ofType: "cer"), let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) as CFData, let certificate = SecCertificateCreateWithData(nil, data),let publicKey = certificate.af.publicKey {
                publicKeyArray.append(publicKey)
            }
        }
        return publicKeyArray
    }
}

3.給Session添加策略(接受質(zhì)詢)

var requestManagerSession: Session = {
    if WTCertificates.rootCA.count > 0, verifyCert {
        let certificates: [SecKey] = WTCertificates.rootCA
        let trustPolicy = PublicKeysTrustEvaluator(keys: certificates, performDefaultValidation: false, validateHost: false)
        let manager = ServerTrustManager(evaluators: [
            "xxx.xxx.com": trustPolicy,
            "xx.xx.jftplus.com": trustPolicy,
            "xxx.xx.com": trustPolicy])// base url 如何域名過(guò)多,可以子類化 ServerTrustManager,并用自己的自定義實(shí)現(xiàn)重寫(xiě) serverTrustEvaluator(forHost:) 方法
        let configuration = URLSessionConfiguration.af.default
        return Session(configuration: configuration, serverTrustManager: manager)
    }
    return MoyaProvider<ApiManager>.defaultAlamofireSession()
}()

4.在Moya中添加requestManagerSession

var JKOtherApiManagerProvider = MoyaProvider<JKOtherApiManager>(endpointClosure: endpointMapping, requestClosure: requestTimeoutClosure, session:requestManagerSession, plugins:[RequestAlertPlugin(), networkPlugin])

OC HTTPS 證書(shū)配置驗(yàn)證

//1 將證書(shū)拖進(jìn)項(xiàng)目

//2 獲取證書(shū)路徑
NSString *certPath = [[NSBundle mainBundle] pathForResource: @"cetus" ofType:@"cer"];
//3 獲取證書(shū)data
NSData *certData = [NSData dataWithContentsOfFile:certPath];
//4 創(chuàng)建AFN 中的securityPolicy
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:[[NSSet alloc] initWithObjects:certData,nil]];
//5 這里就可以添加多個(gè)server證書(shū)
NSSet *dataSet = [[NSSet alloc]initWithObjects:certData, nil];
//6 綁定證書(shū)(不止一個(gè)證書(shū))
[securityPolicy setPinnedCertificates:dataSet];
//7 是否允許無(wú)效證書(shū)
securityPolicy.allowInvalidCertificates = YES;
//8 是否需要驗(yàn)證域名
securityPolicy.validatesDomainName = YES;
uploadManager.securityPolicy = securityPolicy;

我們后臺(tái)給的證書(shū)格式后綴是.pem,以下是用OpenSSL命令將.pem證書(shū)轉(zhuǎn)換為cer格式證書(shū)方法

  1. 打開(kāi)命令行工具,進(jìn)入存放xxx.pem證書(shū)的目錄
  2. 輸入以下命令,將.pem證書(shū)轉(zhuǎn)換為cer格式
openssl x509 -in xxx.pem -inform PEM -out xxx.cer -outform DER
  1. 執(zhí)行完畢后,您將在當(dāng)前目錄下看到生成的xxx.cer文件

注意:轉(zhuǎn)換后的cer證書(shū)文件只包含公鑰,不包含私鑰信息

最后編輯于
?著作權(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)容