
那么我們就先來知道一下 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等問題.但通過 SSL(Secure Socket Layer,安全套接層)或 TLS (Transport Layer Security ,安全層傳輸協(xié)議)的組合使用,加密 HTTP 的通信內(nèi)容。與 SSL 組合使用的 HTTP 被稱為 HTTPS (HTTP 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é)議之上通信接口部分用 SSL 和 TLS 協(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

該方法是在 SessionDelegate 的 didReceive 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é)完畢