最近跟菊廠合做,我司向他們提供SAAS服務。但因爲他們對服務安全管控比較嚴格,內部有專門部門去審覈上線的服務。所以菊廠派人來我司專門對安全這塊作全面排查,期間加了很多班。其中他們提到了對HTTPS密碼套件作配置,當初只知道HTTPS握手後須要非對稱加密的算法,後面查詢了才知道原來還有這一系列的通信過程當中使用的密碼算法。特此寫下文章做爲學習記錄。html
HTTPS是Hyper Text Transfer Protocol Secure的縮寫。是一個計算機系統間進行安全通訊的協議,主要用在瀏覽器和web服務器之間進行通訊。HTTP使用明文進行數據傳輸,而HTTPS則使用加密數據進行傳輸。
HTTPS能夠有效防止黑客在瀏覽器和web服務器之間竊取和修改數據,即便黑客獲取到這些數據,因爲數據已經被加密,對黑客來講實際上是垃圾數據。
HTTPS使用SSL(Secure Socket Layer)或者TLS(Transport Layer Security)協議來創建起瀏覽器和web服務器之間的加密鏈接。golang
Client random
,以及客戶端支持的加密方法。Server random
。Premaster secret
,並使用數字證書中的公鑰,加密這個隨機數,發給服務端。Premaster secret
。上述能夠歸結爲三次通訊,但即便上並不止三次,歸結爲下圖。
服務端和客戶端據約定的加密方法,使用前面的三個隨機數,生成 對話密鑰session key
。服務器和客戶端將會使用該密碼進行對稱加密,保證通訊過程當中信息的安全。web
、算法
在服務端發送CA證書給客戶端後,客戶端須要進行一系列的驗證。瀏覽器
CA證書其實就是第三方機構,做用是檢查證書持有者身份的合法性,並簽發證書,以防證書被僞造或篡改。咱們都知道CA證書是用來驗證網站的安全性,其實,證書除了能夠用來驗證某個網站,還能夠用來驗證某個文件是否被篡改。
因爲證書所涉及面太寬廣,裏面涉及到如何簽發、格式規範等。本文不作過多涉及。安全
密碼套件分爲三大部分:密鑰交換算法,數據加密算法,消息驗證算法(MAC,message authentication code)。密鑰交換算法用於握手過程當中創建信道,通常採用非對稱加密算法。數據加密算法用於信道創建以後的加密傳輸數據,通常採用對稱加密算法。MAC顧名思義是一種哈希,用於驗證消息的完整性,包括整個握手流程的完整性(例如TLS握手的最後一步就是一個對已有的握手消息的全盤哈希計算的過程)。服務器
#openssl ciphers -V
網絡
TLS_DHE_RSA_WITH_AES_256_CBC_SHA是一個密碼學套件的標準名字。
這裏的TLS表明的是TLS協議,若是將來TLS更名,這個名字可能會變,不然會一直是這個名字。WITH是一個分隔單次,WITH前面的表示的是握手過程所使用的非對稱加密方法,WITH後面的表示的是加密信道的對稱加密方法和用於數據完整性檢查的哈希方法。WITH前面一般有兩個單次,第一個單次是約定密鑰交換的協議,第二個單次是約定證書的驗證算法。兩個功能都須要使用非對稱加密算法。交換信息使用的非對稱加密算法是第一個單詞,證書使用的非對稱加密算法是第二個。
有的證書套件,例如TLS_RSA_WITH_AES_256_CBC_SHA,WITH單詞前面只有一個RSA單詞,這時就表示交換算法和證書算法都是使用的RSA,因此只指定一次便可。可選的主要的密鑰交換算法包括: RSA, DH, ECDH, ECDHE
。可選的主要的證書算法包括:RSA, DSA, ECDSA
。二者能夠獨立選擇,並不衝突。AES_256_CBC指的是AES這種對稱加密算法的256位算法的CBC模式,AES自己是一類對稱加密算法的統稱,實際的使用時要指定位數和計算模式,CBC就是一種基於塊的計算模式。最後一個SHA就是代碼計算一個消息完整性的哈希算法。session
客戶端發出請求
ClientHello
因爲客戶端(如瀏覽器)對一些加解密算法的支持程度不同,可是在TLS協議傳輸過程當中必須使用同一套加解密算法才能保證數據可以正常的加解密。在TLS握手階段,客戶端首先要告知服務端,本身支持哪些加密算法,因此客戶端須要將本地支持的加密套件(Cipher Suite)的列表傳送給服務端。除此以外,客戶端還要產生一個隨機數,這個隨機數一方面須要在客戶端保存,另外一方面須要傳送給服務端,客戶端的隨機數須要跟服務端產生的隨機數結合起來產生後面要講到的 Master Secret 。
綜上,在這一步,客戶端主要向服務器提供如下信息:dom
服務器迴應
SeverHello
上圖中,從Server Hello到Server Done,有些服務端的實現是每條單獨發送,有服務端實現是合併到一塊兒發送。Sever Hello和Server Done都是隻有頭沒有內容的數據。
服務端在接收到客戶端的Client Hello以後,服務端須要將本身的證書發送給客戶端。這個證書是對於服務端的一種認證。例如,客戶端收到了一個來自於稱本身是www.alipay.com的數據,可是如何證實對方是合法的alipay支付寶呢?這就是證書的做用,支付寶的證書能夠證實它是alipay,而不是財付通。證書是須要申請,並由專門的數字證書認證機構(CA)經過很是嚴格的審覈以後頒發的電子證書。頒發證書的同時會產生一個私鑰和公鑰。私鑰由服務端本身保存,不可泄漏。公鑰則是附帶在證書的信息中,能夠公開的。證書自己也附帶一個證書電子簽名,這個簽名用來驗證證書的完整性和真實性,能夠防止證書被串改。另外,證書還有個有效期。
Server Key Exchange(證書公鑰發送)
在服務端向客戶端發送的證書中沒有提供足夠的信息(證書公鑰)的時候,還能夠向客戶端發送一個Server Key Exchange。
Cerficate Request(請求客戶端證書)
此外,對於很是重要的保密數據,服務端還須要對客戶端進行驗證,以保證數據傳送給了安全的合法的客戶端。服務端能夠向客戶端發出 Cerficate Request 消息,要求客戶端發送證書對客戶端的合法性進行驗證。好比,金融機構每每只容許認證客戶連入本身的網絡,就會向正式客戶提供USB密鑰,裏面就包含了一張客戶端證書。
跟客戶端同樣,服務端也須要產生一個隨機數發送給客戶端。客戶端和服務端都須要使用這兩個隨機數來產生PreMaster Secret
。
最後服務端會發送一個Server Hello Done消息給客戶端,表示Server Hello消息結束了。
綜上,在這一步,服務器的迴應包含如下內容:
客戶端迴應
Client Key Exchange(發送客戶端證書)
若是服務端須要對客戶端進行驗證,在客戶端收到服務端的 Server Hello 消息以後,首先須要向服務端發送客戶端的證書,讓服務端來驗證客戶端的合法性。
Certificate Verify(證書檢查)接着,客戶端須要對服務端的證書進行檢查,若是證書不是可信機構頒佈、或者證書中的域名與實際域名不一致、或者證書已通過期,就會向訪問者顯示一個警告,由其選擇是否還要繼續通訊。若是證書沒有問題,客戶端就會從服務器證書中取出服務器的公鑰。而後,向服務器發送下面三項信息:
一個隨機數。該隨機數用服務器公鑰加密,防止被竊聽
編碼改變通知,表示隨後的信息都將用雙方商定的加密方法和密鑰發送
客戶端握手結束通知,表示客戶端的握手階段已經結束。這一項同時也是前面發送的全部內容的hash值,用來供服務器校驗
上面第一項的隨機數,是整個握手階段出現的第三個隨機數,它是客戶端使用一些加密算法(例如:RSA, Diffie-Hellman)產生一個48個字節的Key,這個Key叫 PreMaster Secret
。
ChangeCipherSpecChangeCipherSpec
一個獨立的協議,體如今數據包中就是一個字節的數據,用於告知服務端,客戶端已經切換到以前協商好的加密套件(Cipher Suite)的狀態,準備使用以前協商好的加密套件加密數據並傳輸了。
在ChangecipherSpec傳輸完畢以後,客戶端會使用以前協商好的加密套件和Session Secret加密一段 Finish 的數據傳送給服務端,此數據是爲了在正式傳輸應用數據以前對剛剛握手創建起來的加解密通道進行驗證。
服務器的最後迴應
Server Finish
服務端在接收到客戶端傳過來的 PreMaster 加密數據以後,使用私鑰對這段加密數據進行解密,並對數據進行驗證,也會使用跟客戶端一樣的方式生成 Session Secret,一切準備好以後,會給客戶端發送一個 ChangeCipherSpec,告知客戶端已經切換到協商過的加密套件狀態,準備使用加密套件和 Session Secret加密數據了。以後,服務端也會使用 Session Secret 加密一段 Finish 消息發送給客戶端,以驗證以前經過握手創建起來的加解密通道是否成功。
根據以前的握手信息,若是客戶端和服務端都能對Finish信息進行正常加解密且消息正確的被驗證,則說明握手通道已經創建成功,接下來,雙方可使用上面產生的Session Secret
對數據進行加密傳輸了。
tlsconf := &tls.Config{ InsecureSkipVerify: true, MaxVersion: tls.VersionTLS13, MinVersion: tls.VersionTLS12, PreferServerCipherSuites: true, } tlsconf.CipherSuites = []uint16{ tls.TLS_AES_128_GCM_SHA256, tls.TLS_CHACHA20_POLY1305_SHA256, tls.TLS_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, }
https://blog.csdn.net/zhangta...
https://zhuanlan.zhihu.com/p/...
http://blog.chinaunix.net/uid...