一、工作原理
從圖中可以看到,實際上https是在tcp層和http層中間插入了一層ssl層,對應到一般的業務架構中,會在前端設置成nginx + tomcat的模式,用nginx來做證書卸載和負載均衡,tomcat做實際的服務;而在實際的抓包過程中,會發現在常規的tcp三次握手之後,還會有ssl的握手過程,在握手之後的實際的業務請求中,也是ssl協議的報文。
那麼ssl是怎麼做客戶端和服務端的連接建立的呢?我們來看下面的一張圖:
上圖是在tcp連接已經建立好了之後,開始的ssl的連接過程,過程可以分爲以下幾步:
(1) client hello: 客戶端向服務端發出ssl/tls協議的版本號、一個隨機數(client random)和客戶端支持的ssl加密算法列表;
(2) server hello: 服務端確認雙方使用的ssl加密算法,並給出服務端的數字證書和一個隨機數(server random);
(3) 客戶端確認證書有效,然後生成一個新的隨機數(Premaster secret),並使用數字證書中的公鑰加密這個隨機數,發給服務端;
(4) 服務端使用自己的私鑰解析客戶端發來的隨機數;
(5) 客戶端和服務端根據約定的加密算法,使用前面的三個隨機數,生成祕鑰(session key),用來加密接下來的整個會話過程;
以上過程,用表格來表示,即是:
client | server |
---|---|
Client Hello | |
Server Hello 3. certificate 4. server_key_exchange 5. *certificate_request 6. server_hello_done |
|
*certificate 8. client_key_exchange 9. *certificate_verify 10. change_cypher_spec |
|
change_cypher_spec |
下面對連接中的一些細節點做一下解釋:
1. ssl/tls握手過程可以分爲兩種類型:
* 單向認證: 客戶端會認證服務端身份,服務端不會對客戶端進行認證;
* 雙向認證: 客戶端和服務端互相認證,也就是兩者之間會交換證書;
2. 握手過程實際上是通信雙發交換協商一個用於對稱加密的祕鑰的過程,這個過程本身是透明的
3. 在這個過程中會產生單個隨機數: Client Random、Server Random、pre-master secret,其中client server random是明文的,而pre-master是加密的(RSA或DH)。
4. 根據3中,加密的算法可以選擇RSA和DSA算法,這取決於server端使用什麼證書。
* server使用RSA證書:RSA既可以用作簽名也可以用作不對稱加密,pre-master secret就是用server的RSA證書中包含的公鑰加密的;
* server使用DSA證書:DSA只能用作簽名,所以還需要使用DH算法來交換密鑰;
5. 上表中涉及到*的表示在雙向認證中才會使用到。
二、連接過程
我們使用生成的證書,client端ip: 192.168.31.167 server端ip: 192.168.31.176 server端部署nginx,https配置如下:
server {
listen 443 ssl;
server_name ssl.alipay.net;
ssl_certificate ssl/xxx.net.crt;
ssl_certificate_key ssl/xxx.net.key;
#ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
這裏只分析連接過程
1. tcp建聯
可以看到確實首先建立了tcp連接。
2. Client Hello
看一下具體的報文包含了什麼:
這裏可以看到客戶端的session其實還是沒有失效的,這時候如果服務端的session也沒有失效的話,後續的連接過程是可以減少很多的,這個我們後面的實驗再拿出來看。
3. Server Hello
我們可以看到兩個信息:
(1) 這時候在server中,這個session是不存在的,這是因爲重啓nginx導致,實際的session保持是存在的,後面我們實驗中繼續看;
(2) 使用的是DSA算法;
4. server certificate
這個報文只在使用DSA算法的時候纔會使用,我們可以從3中看到現在確實使用的是DSA算法。
5. server key exchange & server hello done
這個報文裏承載了兩個信息,分別是key exchange和結束標識。
6. client_key_exchange & change_cipher_spec & Hello Request
這裏分爲三個報文:
(1) client_key_exchange
包含pre-master secret。客戶端生成第三個隨機數。如果是採用RSA算法,會生成一個48字節隨機數,然後用server的公鑰加密之後再放入報文中;如果是DH算法,這裏發送的就是客戶端的DH參數,之後服務器和客戶端根據DH算法,各自計算出相同的pre-master secret。
(2) change_cipher_spec
客戶端通知服務器開始使用加密方式發送報文。客戶端使用上面的3個隨機數client random, server random, pre-master secret, 計算出48字節的master secret, 這個就是對稱加密算法的密鑰。
(3) hello request
客戶端發送第一個加密報文。使用HMAC算法計算收到和發送的所有握手消息的摘要,然後通過RFC5246中定義的一個僞函數PRF計算出結果,加密後發送。
7. server new session ticket & change_cipher_spec & 第一個報文
session ticket的用途後續再說。
至此,可以看到所有的連接過程如下:
如果是客戶端也需要校驗的,還會多出上面表中*給出的過程。