通信過程當中具有密碼安全學的四個特性,就能夠認爲是「安全」的。這四個特性分別是:算法
HTTPS = HTTP + SSL/TLS,SSL/TLS也應用在應用層(會話層)上,只不過是給HTTP套了一層安全的殼。只要掌握SSL/TLS,也就掌握了HTTPS。 安全
TLS 其實就是有不少子協議組成,組成一個密碼套件,密碼套件命名很是規範,格式很固定。如「ECDHE-RSA-AES256-GCM-SHA384」 :「密鑰交換算法 + 簽名算法 + 對稱加密算法 + 摘要算法」。服務器
完整的意思是:「握手時使用 ECDHE 算法進行密鑰交換,用 RSA 簽名和身份認證,握手後的通訊使用 AES 對稱算法,密鑰長度 256 位,分組模式是 GCM,摘要算法 SHA384 用於消息認證和產生隨機數。」session
加密解密都使用同一個密鑰,目前經常使用的只有 AES 和 ChaCha20。 可是有一個很大的問題:如何把密鑰安全地傳遞給對方,術語叫「密鑰交換」。dom
非對稱加密能夠解決「密鑰交換」的問題。網站(服務器)祕密保管私鑰,在網上任意分發公鑰,你想要登陸網站只要用公鑰加密就好了,密文只能由私鑰持有者才能解密。而黑客由於沒有私鑰,因此就沒法解密密文。函數
RSA 是最著名的一種,不過因爲它的安全性基於「整數分解」的數學難題,基於兩個超大素數乘積做爲生成密鑰的材料,想要根據公鑰推出私鑰是很是困難的;計算過程很是複雜,運算速度很慢。實用性幾乎爲0;但目前主流使用的是ECC,比起 RSA,ECC 在安全強度和性能上都有明顯的優點。性能
// 對稱加密 AES128 則是 13MB/S
aes_128_cbc enc/dec 1000 times : 0.97ms, 13.11MB/s
// 非對稱加密1024位
rsa_1024 enc/dec 1000 times : 138.59ms, 93.80KB/s
rsa_1024/aes ratio = 143.17
// 非對稱加密2048位
rsa_2048 enc/dec 1000 times : 840.35ms, 15.47KB/s
rsa_2048/aes ratio = 868.13
複製代碼
既然非對稱加密可以解決密鑰交換的問題,那咱們徹底能夠先用非對稱加密進行密鑰交換,再用對稱加密進行通信便可。網站
由於非對稱密鑰有單向性,所謂的單向性,就是公鑰加密私鑰解密,私鑰加密公鑰解密;這樣就能把對稱密鑰的安全交換了,後面加密解密都用對稱密鑰。加密
具體的作法是:spa
可是,還會存在另外兩個問題:
對於完整性,採用的是摘要算法,也是常說的散列函數/哈希函數。
摘要算法只能進行加密,沒有解密。因此就能經過「數字摘要」來保證數據的完整性。
不過摘要算法不具備機密性,若是明文傳輸也不安全,由於咱們已經經過非對稱加密把「會話密鑰」(session key)安全交換了。因此能夠利用會話密鑰(對稱加密)進行加密解密。這樣就能夠保證數據的完整性了。
那身份認證和不能否認呢?
現實生活中咱們要解決這兩個問題,用簽名和蓋章;由於混合加密用的「公鑰」和「私鑰」都具備單向性,徹底能夠同時實現「身份認證」和「不能否認」的數字簽名。
數字簽名的原理其實很簡單,就是把公鑰私鑰的用法反過來,以前是公鑰加密、私鑰解密,如今是私鑰加密、公鑰解密。
但又由於非對稱加密效率過低,因此私鑰只加密原文的摘要,這樣運算量就小的多,並且獲得的數字簽名也很小,方便保管和傳輸。
簽名和公鑰同樣徹底公開,任何人均可以獲取。但這個簽名只有用私鑰對應的公鑰才能解開,拿到摘要後,再比對原文驗證完整性,就能夠像簽署文件同樣證實消息確實是你發的。
客戶端 --> 服務器:客戶端的版本號、支持的密碼套件,還有一個隨機數(Client Random)
服務端 --> 客戶端:對一下客戶端的版本號、選擇的客戶端列表的密碼套件如:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA38四、隨機數隨機數(Server Random)
服務端 --> 客戶端:服務端證書(Server Certificate)
服務端 --> 客戶端:發送Server Key Exchange類型的請求,攜帶橢圓曲線的公鑰(Server Params)用以實現密鑰交換算法,另附私鑰簽名(預防別人假冒我,籤個名蓋個章)。
服務端 --> 客戶端:發送完畢
客戶端、服務端分別使用Client Params、Server Params 經過 ECDHE算法計算出隨機值pre-master;
而後用 Client Random、Server Random 和 Pre Random 三個值(隨機數)做爲原材料,用PRF僞隨機數函數(利用密碼套件的摘要算法再次強化結果值master secret的隨機性)計算出主密鑰 Master Secret;
主密鑰並非會話祕鑰,還會再用PRF擴展出更多的密鑰,好比客戶端發送用的會話密鑰(client_write_key)、服務器發送用的會話密鑰(server_write_key);避免只用一個密鑰帶來的安全隱患。
客戶端 --> 服務端:客戶端發一個「Change Cipher Spec」,而後再發一個「Finished」消息,把以前全部發送的數據作個摘要,再加密一下,讓服務器作個驗證;
服務端 --> 客戶端:服務器也是一樣的操做,發「Change Cipher Spec」和「Finished」消息,雙方都驗證加密解密 OK,握手正式結束。
整體來講TLS握手就是經過交換三個隨機數,而後計算出主會話密鑰;因爲安全性,會繼續擴展出更多的臨時密鑰。保證通信過程的絕對安全。
第三個隨機數 pre-master 是由Client Params、Server Params 經過 ECDHE算法計算出來的,在客戶端給服務端發送這個 Client Params 以前,會根據服務端給本身的簽名和證書對服務器進行身份驗證。因此才能保障 Client Params 安全的到達服務端。也就實現了服務器端證實了本身是真的服務器端。
若是你還有不少疑問,或者不清晰的地方,這裏我強烈推薦訂閱這個專欄,透視HTTP協議,講解得很是不錯。