Alamofire安全認(rèn)證策略

作為一個(gè)有牌面的人, 肯定不只是學(xué)會(huì)怎么用它的方法就行了. 得建立起系統(tǒng)的知識(shí)體系.

那么我們就先來知道一下 HTTPS 以及加密的相關(guān)知識(shí), 畢竟這也是面試比較常問到的點(diǎn).

HTTP 與 HTTPS

HTTP 協(xié)議中,發(fā)送的內(nèi)容是以明文的形式傳遞的。這就導(dǎo)致了以下幾個(gè) HTTP 的不足:

  • 參數(shù), 頭信息等全為明文內(nèi)容,很容易被竊聽
  • 不對雙方的身份作驗(yàn)證,容易被偽裝
  • 無法驗(yàn)證數(shù)據(jù)的完整性,數(shù)據(jù)容易被篡改

也就是說很容易會(huì)被抓包, cookie等問題.但通過 SSLSecure Socket Layer,安全套接層)或 TLSTransport Layer Security ,安全層傳輸協(xié)議)的組合使用,加密 HTTP 的通信內(nèi)容。與 SSL 組合使用的 HTTP 被稱為 HTTPSHTTP Secure,超文本傳輸安全協(xié)議)或 HTTP over SSL。

HTTPS的特點(diǎn)
  • HTTPS 在傳輸數(shù)據(jù)之前需要客戶端(瀏覽器)與服務(wù)端(網(wǎng)站)之間進(jìn)行一次握手,在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。

  • TLS / SSL 中使用了非對稱加密,對稱加密以及 HASH 算法。其中非對稱加密算法用于在握手過程中加密生成的密碼,對稱加密算法用于對真正傳輸?shù)臄?shù)據(jù)進(jìn)行加密,而 HASH 算法用于驗(yàn)證數(shù)據(jù)的完整性。

  • TLS 握手過程中如果有任何錯(cuò)誤,都會(huì)使加密連接斷開,從而阻止了隱私信息的傳輸。

需要注意的是 HTTPS 并非是一種新的協(xié)議, 只是基于 HTTP 協(xié)議之上通信接口部分用 SSLTLS 協(xié)議代替而已。

HTTPS的執(zhí)行過程
對稱加密和非對稱加密
  • 對稱加密:

即加密的密鑰和解密的密鑰相同. 也就是所說的私鑰加密, 信息的發(fā)送方和接收方使用同一個(gè)密鑰去加密和解密數(shù)據(jù)。

  • 非對稱加密

非對稱加密將密鑰分為公鑰和私鑰,公鑰可以公開,私鑰需要保密,客戶端公鑰加密的數(shù)據(jù),服務(wù)端可以通過私鑰來解密.

個(gè)人建議理解方法: 非對稱性加密理解為鎖是公開的. 任何人通過公鑰把數(shù)據(jù)鎖到里面, 只有服務(wù)器 (擁有私鑰的人可以打開鎖.)

HTTPS采用的加密方式

HTTPS 采用混合加密, 值得一提的是 SSL 使用的是非對稱性加密.

SSL加密并不保護(hù)數(shù)據(jù)中心本身,而是確保了SSL加密設(shè)備的數(shù)據(jù)中心安全,可以監(jiān)控企業(yè)中來往于數(shù)據(jù)中心的最終用戶流量。

???♂?問: 為什么 HTTPS 采用混合加密的模式呢?為什么不全用公開密鑰加密?

答: 因?yàn)榉菍ΨQ性加密效率低, 占用資源高, 但因其利用的往往是數(shù)學(xué)難題, 因此安全性更好。所以 HTTPS 充分利用兩者優(yōu)勢,在交換秘鑰環(huán)節(jié)使用公開密鑰加密方式,之后的簡歷通信交換報(bào)文階段則用時(shí)共享秘鑰加密方式.


上圖步驟一就是非對稱性加密秘鑰, 步驟二數(shù)據(jù)交互時(shí)采用對稱性加密方式.
簡單來說就是通過非對稱性加密 加密一個(gè)隨機(jī)數(shù), 這個(gè)隨機(jī)數(shù)為對稱性加密的鑰匙.

舉個(gè)例子: AES256 對稱性加密, 他有一個(gè) key, 這個(gè) key 我們使用 RSA 去加密, 那么就構(gòu)成了上述這種結(jié)構(gòu), 通過非對稱性加密去加密對稱性加密的鑰匙.

Alamofire中的安全認(rèn)證

直接找 ServerTrustPolicy 文件.
步驟 1??: ServerTrustPolicyManager 初始化創(chuàng)建了一個(gè)
[String:ServerTrustPolicy] 屬性.
步驟 2??: 找到 ServerTrustPolicy, 是一個(gè)枚舉

public enum ServerTrustPolicy {
    case performDefaultEvaluation(validateHost: Bool)
    case performRevokedEvaluation(validateHost: Bool, revocationFlags: CFOptionFlags)
    case pinCertificates(certificates: [SecCertificate], validateCertificateChain: Bool, validateHost: Bool)
    case pinPublicKeys(publicKeys: [SecKey], validateCertificateChain: Bool, validateHost: Bool)
    case disableEvaluation
    case customEvaluation((_ serverTrust: SecTrust, _ host: String) -> Bool)
  • .performDefaultEvaluation 默認(rèn)策略,只有合法證書才能通過驗(yàn)證

  • .performRevokedEvaluation 對注銷證書做的一種額外設(shè)置

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

pinPublicKeys(publicKeys: [SecKey], validateCertificateChain: Bool, validateHost: Bool)

參數(shù)1:certificates 證書
參數(shù)2:validateCertificateChain 代表是否驗(yàn)證證書鏈, false 則只驗(yàn)證根證書.
參數(shù)3:validateHost 代表是否驗(yàn)證子地址

使用 ??:

let serverTrustPlolicies:[String: ServerTrustPolicy] = [
    hostUrl: .pinCertificates(
        certificates: ServerTrustPolicy.certificates(),
        validateCertificateChain: true,
        validateHost: true)
]
let sessionManger = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPlolicies))

sessionManger.request(urlString).response { (defaultResponse) in
    print(defaultResponse)
}
  • .pinPublicKeys 公鑰驗(yàn)證模式,代表客戶端會(huì)將服務(wù)器返回的證書和本地保存的證書中的 PublicKey部分 進(jìn)行校驗(yàn),如果正確,才繼續(xù)執(zhí)行。
pinPublicKeys(publicKeys: [SecKey], validateCertificateChain: Bool, validateHost: Bool)

參數(shù)1: 第一個(gè)參數(shù)傳公鑰
參數(shù)2:validateCertificateChain 代表是否驗(yàn)證證書鏈, false 則只驗(yàn)證根證書.
參數(shù)3:validateHost 代表是否驗(yàn)證子地址

公鑰驗(yàn)證模式的好處是,只要公鑰不變,就可以一直使用,不用擔(dān)心證書問題。

  • .disableEvaluation 該選項(xiàng)下驗(yàn)證一直都是通過的,無條件信任。

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


主要方法:

public func evaluate(_ serverTrust: SecTrust, forHost host: String) -> Bool

該方法是在 SessionDelegatedidReceive challenge 方法中調(diào)用的.


該類中還提供了一些輔助方法:

  • 讀取證書
public static func certificates(in bundle: Bundle = Bundle.main) -> [SecCertificate] 

private func certificateData(for certificates: [SecCertificate]) -> [Data]

private func certificateData(for trust: SecTrust) -> [Data] 
  • 讀取公鑰
public static func publicKeys(in bundle: Bundle = Bundle.main) -> [SecKey]

private static func publicKeys(for trust: SecTrust) -> [SecKey] 

private static func publicKey(for certificate: SecCertificate) -> SecKey? 
  • 獲取驗(yàn)證結(jié)果
private func trustIsValid(_ trust: SecTrust) -> Bool

以上就是 HTTPS 的流程以及 Alamofire 中安全驗(yàn)證流程. 總結(jié)完畢

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

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

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