在網絡如此發達的今天,網絡安全已經和每一個人息息相關了。今天咱們就一塊兒來了解一下網絡安全方面的相關知識。算法
咱們知道,在HTTP協議中,發送的內容是以明文的形式傳遞的。這就致使瞭如下幾個缺陷:swift
爲了解決上面👆幾個缺陷,蘋果官方推薦使用HTTPS傳輸協議。瀏覽器
HTTPS協議是由SSL/TLS+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議。重要的是比HTTP更安全。安全
在瞭解HTTPS協議以前,咱們須要先有一點密碼學基礎。bash
明文:是指未被加密過的原始數據
複製代碼
密文:明文被某個加密方式(算法)加密後,就變成了密文。密文能夠被解密獲得明文
複製代碼
密鑰:是在明文轉換爲密文的算法中所使用的參數。
密鑰分爲對稱密鑰和非對稱密鑰。分別對應對稱加密和非對稱加密。
複製代碼
對稱加密:對稱加密又叫作私鑰加密,即信息的發送方和接收方使用同一個密鑰去加密和解密數據。
複製代碼
對稱加密的特色是算法公開、加密和解密速度快,適合於對大數據量進行加密。服務器
對稱加密加密過程:明文 + 加密算法 + 私鑰 => 密文 對稱加密解密過程:密文 + 解密算法 + 私鑰 => 明文網絡
非對稱加密:非對稱加密也叫作公鑰加密。非對稱加密使用一對密鑰,即公鑰和私鑰,且兩者成對出現。用公鑰或私鑰中的任何一個進行加密,用另外一個進行解密。
複製代碼
非對稱加密的缺點是加密和解密花費時間長、速度慢,只適合對少許數據進行加密。session
被公鑰加密過的密文只能被私鑰解密。 加密過程:明文 + 加密算法 + 公鑰 => 密文 解密過程:密文 + 解密算法 + 私鑰 => 明文ide
被私鑰加密過的密文只能被公鑰解密。 加密過程:明文 + 加密算法 + 私鑰 => 密文 解密過程:密文 + 解密算法 + 公鑰 => 明文函數
非對稱加密比對稱加密更加安全,那麼HTTPS中使用的是非對稱加密嗎?不是的。https使用的是混合加密的方式。那什麼是混合加密呢?
如上圖所示,HTTPS協議在鏈接時使用的是非對稱加密。在數據傳輸過程當中,使用的是對稱加密。
由於非對稱加密速度慢,不合適在數據傳輸過程加密。因此在傳輸過程當中使用對稱加密。而爲了網絡請求的安全性,因此在鏈接過程當中使用了非對稱加密。
那麼HTTPS的通信過程是怎樣的呢?
舉個栗子🌰:
let urlBD = "https://47.105.168.156:20199/"
Alamofire.request(urlBD, method: .get, parameters: ["users": "bar"])
.response { (response) in
print(response)
}
複製代碼
在上面👆的栗子中,咱們向一個https地址發起了網絡請求。運行以後會發現報了一些錯誤。
TIC SSL Trust Error [1:0x600000a592c0]: 3:0
...
Task <C47E510C-D9F5-4C62-9EB0-D58FFF71A638>.<1> finished with error - code: -1202
Task <C47E510C-D9F5-4C62-9EB0-D58FFF71A638>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be 「47.105.168.156」 which could put your confidential information at risk."
複製代碼
根據錯誤信息,大概是說服務器的證書失效。那麼這個錯誤應該如何修復呢?想要修復這個錯誤,咱們應該知道,這個錯誤是什麼時候打印的。
咱們從錯誤信息中看到有 finished with error
,那麼咱們在 didCompleteWithError
函數中斷點調試一下。
斷點後發現,在進入 didCompleteWithError
回調函數以前,已經打印了錯誤信息。因此,咱們的猜想不成立。
咱們知道,全部的網絡請求都會走 SessionDelegate
的回調。既然不在 didCompleteWithError
回調函數,那會不會在其餘回調函數呢?而後咱們就會找到這樣一個回調函數:
從註釋文檔來看,這是和證書相關的回調。咱們斷點調試一下,發現確實會來到這裏。而且會調用 delegate.urlSession
回調函數。
就是這個回調函數,並且會由於紅框中的判斷沒有成功而直接跳出執行。因此,這裏就是錯誤的關鍵,這其實就是常說的 網絡挑戰。
session.serverTrustPolicyManager
是 URLSession
的一個關聯屬性。那它是什麼時候設置的呢? 還記得在【Alamofire之SessionManager】分析 SessionManager
初始化的時候見過這個屬性,可是當時沒有分析。
因此咱們應該在 SessionManager
的初始化時應該多一個參數 serverTrustPolicyManager
。
咱們自定義一個 SessionManager
:
func boManager() -> SessionManager {
// 第一個參數是要信任的主機host
let policies: [String: ServerTrustPolicy] = [
"47.105.168.156": .pinCertificates(certificates: ServerTrustPolicy.certificates(), validateCertificateChain: true, validateHost: true)
]
// 其他參數使用默認值
let sessionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies))
return sessionManager
}
複製代碼
使用 ServerTrustPolicyManager
初始化 SessionManager
。
ServerTrustPolicyManager
須要一個字典參數 policies
。 字典的key是你認證的主機地址。value是一個枚舉 ServerTrustPolicy
。
枚舉 ServerTrustPolicy
有不少個case,小夥伴能夠根據文檔選擇本身的方式。這裏使用 pinCertificates
固定證書認證舉例。
須要服務器給你一個證書,放入工程中。而後再使用自定義的 SessionManager
請求網絡。
let urlBD = "https://47.105.168.156:20199/"
// 使用自定義SessionManager網絡請求
self.sessionManager = boManager()
self.sessionManager?.request(urlBD)
.response { (response) in
print(response)
}
複製代碼
從新運行,就會發現不會報以前的錯誤了。
若是小夥伴只是測試,或者本身寫個demo,還可使用 .disableEvaluation
不驗證證書。
// 不驗證證書
let policies: [String: ServerTrustPolicy] = [
"47.105.168.156": .disableEvaluation
]
複製代碼
可是這樣會很危險,小夥伴們慎用。
看到這裏,不少小夥伴可能會有疑問了。由於平時咱們開發中沒有這樣設置過,都是直接網絡請求,也沒有報錯。這是由於,上面適用的狀況是自簽證書。而咱們平時更多使用的是CA證書。
那麼CA證書又是如何工做的呢?請看下圖:
以上就是本篇Alamofire安全認證的所有內容。如有不足之處,請評論指正。