1. 程式人生 > >SSL-TLS 雙向認證(一) -- SSL-TLS工作原理

SSL-TLS 雙向認證(一) -- SSL-TLS工作原理

一: SSL/TLS介紹

什麼是SSL,什麼是TLS呢?官話說SSL是安全套接層(secure sockets layer),TLS是SSL的繼任者,叫傳輸層安全(transport layer security)。說白點,就是在明文的上層和TCP層之間加上一層加密,這樣就保證上層資訊傳輸的安全。如HTTP協議是明文傳輸,加上SSL層之後,就有了雅稱HTTPS。它存在的唯一目的就是保證上層通訊安全的一套機制。它的發展依次經歷了下面幾個時期,像手機軟體升級一樣,每次更新都新增或去除功能,比如引進新的加密演算法,修改握手方式等。
SSL1.0: 已廢除
SSL2.0: RFC6176,已廢除
SSL3.0: RFC6101,基本廢除
TLS1.0

: RFC2246,目前大都支援此種方式
TLS1.1: RFC4346
TLS1.2: RFC5246,部分伺服器支援,沒有廣泛使用
TLS1.3: IETF正在醞釀中
下面我們將介紹TLS1.x 如何保證通訊安全。

二: CA & SSL Server & SSL Client 介紹

如何保證安全呢?你說安全就安全嗎,究竟是怎麼實現的呢?絕對安全嗎?
哈,有人的地方就有江湖,有江湖的地方就沒有絕對的安全。但SSL/TLS確實可以極大程度保證資訊保安。下面根據圖一 SSL/TLS 工作流來一覽實現過程。

2.1 SSL/TLS 工作流

SSL workflow

圖一 SSL/TLS 工作流

CA: 證書授權中心( certificate authority)。 它呢,類似於國家出入境管理處一樣,給別人頒發護照;也類似於國家工商管理局一樣,給公司企業頒發營業執照。
它有兩大主要性質:
1) CA本身是受信任的 // 國際認可的
2) 給他受信任的申請物件頒發證書 // 和辦理護照一樣,要確定你的合法身份,你不能是犯罪分子或造反派。當然,你需要被收保護費,同時,CA可以隨時吊銷你的證書。
證書長啥樣?其實你的電腦中有一堆CA證書。你可以看一看:
360瀏覽器: 選項/設定-> 高階設定 -> 隱私於安全 -> 管理 HTTPS/SSL 證書 -> 證書頒發機構
火狐瀏覽器: 首選項 -> 高階 -> 證書 -> 檢視證書 -> 證書機構
chrome瀏覽器: 設定 -> 高階 -> 管理證書 -> 授權中心
ubuntu: /etc/ssl/certs
這些都是 CA 的證書!

CA 的證書 ca.crt 和 SSL Server的證書 server.crt 是什麼關係呢?


1) SSL Server 自己生成一個 私鑰/公鑰對。server.key/server.pub // 私鑰加密,公鑰解密!
2) server.pub 生成一個請求檔案 server.req. 請求檔案中包含有 server 的一些資訊,如域名/申請者/公鑰等。
3) server 將請求檔案 server.req 遞交給 CA,CA驗明正身後,將用 ca.key和請求檔案加密生成 server.crt
4) 由於 ca.key 和 ca.crt 是一對, 於是 ca.crt 可以解密 server.crt.
在實際應用中:如果 SSL Client 想要校驗 SSL server.那麼 SSL server 必須要將他的證書 server.crt 傳給 client.然後 client 用 ca.crt 去校驗 server.crt 的合法性。如果是一個釣魚網站,那麼CA是不會給他頒發合法server.crt證書的,這樣client 用ca.crt去校驗,就會失敗。比如瀏覽器作為一個 client,你想訪問合法的淘寶網站https://www.taobao.com, 結果不慎訪問到 https://wwww.jiataobao.com ,那麼瀏覽器將會檢驗到這個假淘寶釣魚網站的非法性,提醒使用者不要繼續訪問!這樣就可以保證了client的所有https訪問都是安全的。

2.2 單向認證雙向認證

何為SSL/TLS單向認證,雙向認證?
單向認證指的是隻有一個物件校驗對端的證書合法性。
通常都是client來校驗伺服器的合法性。那麼client需要一個ca.crt,伺服器需要server.crt,server.key
雙向認證指的是相互校驗,伺服器需要校驗每個client,client也需要校驗伺服器。
server 需要 server.key 、server.crt 、ca.crt
client 需要 client.key 、client.crt 、ca.crt

2.3 證書詳細工作流

證書工作流

圖二 證書詳細工作流

1)申請認證:伺服器需自己生成公鑰私鑰對pub_svr & pri_svr,同時根據 pub_svr 生成請求檔案 csr,提交給CA,csr中含有公鑰、組織資訊、個人資訊(域名)等資訊。(圖一中server.req就是csr請求檔案)
2)稽核資訊:CA通過線上、線下等多種手段驗證申請者提供資訊的真實性,如組織是否存在、企業是否合法,是否擁有域名的所有權等。
3)簽發證書:如資訊稽核通過,CA會向申請者簽發認證檔案-證書。
證書包含以下資訊:申請者公鑰、申請者的組織資訊和個人資訊、簽發機構 CA的資訊、有效時間、證書序列號等資訊的明文,同時包含一個簽名。
簽名的產生演算法:首先,使用雜湊函式計算公開的明文資訊的資訊摘要,然後,採用 CA的私鑰對資訊摘要進行加密,密文即簽名。(圖一中生成server.crt)
4)返回證書:client如果請求驗證伺服器,伺服器需返回證書檔案。(圖一中handshake傳回server.crt)
5)client驗證證書:client讀取證書中的相關的明文資訊,採用相同的雜湊函式計算得到資訊摘要,然後,利用對應 CA的公鑰解密簽名資料,對比證書的資訊摘要,如果一致,則可以確認證書的合法性,即公鑰合法。客戶端然後驗證證書相關的域名資訊、有效時間是否吊銷等資訊。
客戶端會內建信任CA的證書資訊(包含公鑰),如果CA不被信任,則找不到對應 CA的證書,證書也會被判定非法。(圖一中check可選,我們可以選擇不驗證伺服器證書的有效性)
6)祕鑰協商:驗證通過後,Server和Client將進行祕鑰協商。接下來Server和Client會採用對稱祕鑰加密。(對稱加密時間效能優)(圖一中 pre-master/change_cipher_spec/encrypted_handshake_message過程)
7)資料傳輸:Server和Client採用對稱祕鑰加密解密資料。

2.4 SSL/TLS單向認證流程

單項認證

(1)client_hello

客戶端發起請求,以明文傳輸請求資訊,包含版本資訊,加密套件候選列表,壓縮演算法候選列表,隨機數,擴充套件欄位等資訊,相關資訊如下:

  • 支援的最高TSL協議版本version,從低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,當前基本不再使用低於 TLSv1 的版本;
  • 客戶端支援的加密套件 cipher suites 列表, 每個加密套件對應前面 TLS 原理中的四個功能的組合:認證演算法 Au (身份驗證)、金鑰交換演算法 KeyExchange(金鑰協商)、對稱加密演算法 Enc (資訊加密)和資訊摘要 Mac(完整性校驗);
  • 支援的壓縮演算法 compression methods 列表,用於後續的資訊壓縮傳輸;
  • 隨機數 random_C,用於後續的金鑰的生成;
  • 擴充套件欄位 extensions,支援協議與演算法的相關引數以及其它輔助資訊等,常見的 SNI 就屬於擴充套件欄位,後續單獨討論該欄位作用。

(2).server_hello+server_certificate+sever_hello_done

  • server_hello, 服務端返回協商的資訊結果,包括選擇使用的協議版本 version,選擇的加密套件 cipher suite,選擇的壓縮演算法 compression method、隨機數 random_S 等,其中隨機數用於後續的金鑰協商;
  • server_certificates, 伺服器端配置對應的證書鏈,用於身份驗證與金鑰交換;
  • server_hello_done,通知客戶端 server_hello 資訊傳送結束;

(3).證書校驗

  • [證書鏈]的可信性 trusted certificate path,方法如前文所述;
  • 證書是否吊銷 revocation,有兩類方式離線 CRL 與線上 OCSP,不同的客戶端行為會不同;
  • 有效期 expiry date,證書是否在有效時間範圍;
  • 域名 domain,核查證書域名是否與當前的訪問域名匹配,匹配規則後續分析;

(4).client_key_exchange+change_cipher_spec+encrypted_handshake_message

  • client_key_exchange,合法性驗證通過之後,客戶端計算產生隨機數字 Pre-master,並用證書公鑰加密,傳送給伺服器;
  • 此時客戶端已經獲取全部的計算協商金鑰需要的資訊:兩個明文隨機數 random_C 和 random_S 與自己計算產生的 Pre-master,計算得到協商金鑰;
    enc_key=Fuc(random_C, random_S, Pre-Master)
  • change_cipher_spec,客戶端通知伺服器後續的通訊都採用協商的通訊金鑰和加密演算法進行加密通訊;
  • encrypted_handshake_message,結合之前所有通訊引數的 hash 值與其它相關資訊生成一段資料,採用協商金鑰 session secret 與演算法進行加密,然後傳送給伺服器用於資料與握手驗證;

(5).change_cipher_spec+encrypted_handshake_message

  • 伺服器用私鑰解密加密的 Pre-master 資料,基於之前交換的兩個明文隨機數 random_C 和 random_S,計算得到協商金鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
  • 計算之前所有接收資訊的 hash 值,然後解密客戶端傳送的 encrypted_handshake_message,驗證資料和金鑰正確性;
  • change_cipher_spec, 驗證通過之後,伺服器同樣傳送 change_cipher_spec 以告知客戶端後續的通訊都採用協商的金鑰與演算法進行加密通訊;
  • encrypted_handshake_message, 伺服器也結合所有當前的通訊引數資訊生成一段資料並採用協商金鑰 session secret 與演算法加密併發送到客戶端;

(6).握手結束

客戶端計算所有接收資訊的 hash 值,並採用協商金鑰解密 encrypted_handshake_message,驗證伺服器傳送的資料和金鑰,驗證通過則握手完成;

(7).加密通訊

開始使用協商金鑰與演算法進行加密通訊。

2.5 實際wireshark分析

這裡寫圖片描述
我們搭建的SSL/TLS伺服器是192.168.111.100,client是192.168.111.101. client 需要認證 server的合法性。
我們只看 TLSv1.1 的資料包:
第一包(No. 25) Client Hello 包,即SSL/TLS單向認證流程的(1)
第二包(No. 27) Server Hello 包,包含伺服器證書等。即SSL/TLS單向認證流程的(2)
第三包(No. 28) 伺服器證書驗證完成,同時傳送client key exchange+change cipher spec + encrypted handshake message.即SSL/TLS單向認證流程的(4)
第四包(No. 29)祕鑰協商,change cipher spec + encrypted hanshake message.即SSL/TLS單向認證流程的(5)
第五包(No. 30)握手完成。開始上層資料傳輸。SSL/TLS單向認證流程的(7)

2.6 SSL/TLS雙向認證流程

和單向認證幾乎一樣,只是在client認證完伺服器證書後,client會將自己的證書client.crt傳給伺服器。伺服器驗證通過後,開始祕鑰協商。
實際wireshark分析:
這裡寫圖片描述

和單向認證一樣:
我們搭建的SSL/TLS伺服器是192.168.111.100,client是192.168.111.101. client 需要認證 server的合法性,server也需要認證client的合法性!
我們只看 TLSv1.1 的資料包:
第一包(No. 55) Client Hello 包,即SSL/TLS單向認證流程的(1)
第二包(No. 57) Server Hello 包,包含伺服器證書等。即SSL/TLS單向認證流程的(2)
第三包(No. 60) 伺服器證書驗證完成,同時傳送客戶端的證書client.crt ,同時包含client key exchange+change cipher spec + encrypted handshake message.即SSL/TLS單向認證流程的(4)
第四包(No. 61)伺服器驗證客戶端證書的合法性。通過後進行祕鑰協商,change cipher spec + encrypted hanshake message.即SSL/TLS單向認證流程的(5)
重傳包(No. 62)由於網路原因,TCP重傳第No. 60包。
第五包(No. 64)握手完成。開始上層資料傳輸。SSL/TLS單向認證流程的(7)

2.7 證書等格式說明

crt/key/req/csr/pem/der等拓展名都是什麼東東?
1)通常來說, .crt 表示證書, .key表示私鑰, .req 表示請求檔案,.csr也表示請求檔案, .pem表示pem格式,.der表示der格式。
檔案拓展名你可以隨便命名。只是為了理解需要而命名不同的拓展名。但檔案中的資訊是有格式的,和exe,PE格式一樣,證書有兩種格式。
pem格式和der格式。所有證書,私鑰等都可以是pem,也可以是der格式,取決於應用需要。
pem和der格式可以互轉:

    openssl x509 -in ca.crt -outform DER -out ca.der  //pem -> der
    openssl x509 -inform der -in ca.der -out ca.pem    // der -> pem
  • 1
  • 2
pem格式:經過加密的文字檔案,一般有下面幾種開頭結尾: 
  • 1
  • 2
    -----BEGIN RSA PRIVATE KEY-----
    -----END RSA PRIVATE KEY-----
    or:
   -----BEGIN CERTIFICATE REQUEST-----
   -----END CERTIFICATE REQUEST-----
    or:
   ----BEGIN CERTIFICATE-----
  -----END CERTIFICATE-----
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

der格式: 經過加密的二進位制檔案。

2) 證書中含有 申請者公鑰、申請者的組織資訊和個人資訊、簽發機構 CA的資訊、有效時間、證書序列號等資訊的明文,同時包含一個簽名。如檢視百度證書詳細資訊。
a) 先下載百度證書
火狐瀏覽器訪問https://www.baidu.com/, 點選左上角綠色小鎖,點擊向右箭頭,點選更多資訊,點選檢視證書,點選詳細資訊,點選匯出。即可匯出百度的證書 baiducom.crt

b) 命令檢視證書詳細資訊

openssl x509 -noout -text -in baiducom.crt
  • 1

baiducert

詳細資訊中,有一個欄位: X509v3 Basic Constraints: CA: FALSE
該欄位指出該證書是否是 CA證書,還是一般性的非 CA 證書。詳細描述見 RFC5280#section-4.2.1.9,同時 RFC5280 也詳細描述證書工作方式等。
[注]: CA:TRUE 或 CA: FALSE 這些證書中的引數通通都可以自己設定,那麼有同學會問,如果有個釣魚網站自籤一個證書,將CA欄位設定為TRUE, 那麼是不是這個證書就能完美通過SSL/TLS互動呢?
其實不然,CA欄位設定為TRUE, 只是代表著該證書是CA證書,而不是意味著CA機構頒發的CA證書。在伺服器和使用者[瀏覽器]互動過程中,伺服器傳過來的證書如果是自籤的CA證書,那麼瀏覽器也會檢查不通過(因為沒有合法CA機構的CA證書能校驗過該伺服器傳過來的證書),就會提醒使用者謹慎訪問。

3) 私鑰加密,公鑰解密!

2.8 SSL/TLS和 Openssl,mbedtls是什麼關係?

SSL/TLS是一種工作原理,openssl和mbedtls是SSL/TLS的具體實現,很類似於 TCP/IP協議和socket之間的關係。

三: 本地生成SSL相關檔案

3.1 證書生成指令碼

我們自己本地使用 makefile.sh 指令碼建立一個CA(ca.crt + ca.key),用這個CA給server和client分別頒發證書。

makefile.sh

# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
# * Neither the name of the axTLS project nor the names of its
#   contributors may be used to endorse or promote products derived
#   from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

#
# Generate the certificates and keys for testing.
#


PROJECT_NAME="TLS Project"

# Generate the openssl configuration files.
cat > ca_cert.conf << EOF  
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
 O                      = $PROJECT_NAME Dodgy Certificate Authority
EOF

cat > server_cert.conf << EOF  
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
 O                      = $PROJECT_NAME
 CN                     = 192.168.111.100
EOF

cat > client_cert.conf << EOF  
[ req ]
distinguished_name     = req_distinguished_name
prompt                 = no

[ req_distinguished_name ]
 O                      = $PROJECT_NAME Device Certificate
 CN                     = 192.168.111.101
EOF

mkdir ca
mkdir server
mkdir client
mkdir certDER

# private key generation
openssl genrsa -out ca.key 1024
openssl genrsa -out server.key 1024
openssl genrsa -out client.key 1024

# cert requests
openssl req -out ca.req -key ca.key -new \
            -config ./ca_cert.conf
openssl req -out server.req -key server.key -new \
            -config ./server_cert.conf 
openssl req -out client.req -key client.key -new \
            -config ./client_cert.conf 

# generate the actual certs.
openssl x509 -req -in ca.req -out ca.crt \
            -sha1 -days 5000 -signkey ca.key
openssl x509 -req -in server.req -out server.crt \
            -sha1 -CAcreateserial -days 5000 \
            -CA ca.crt -CAkey ca.key
openssl x509 -req -in client.req -out client.crt \
            -sha1 -CAcreateserial -days 5000 \
            -CA ca.crt -CAkey ca.key

openssl x509 -in ca.crt -outform DER -out ca.der
openssl x509 -in server.crt -outform DER -out server.der
openssl x509 -in client.crt -outform DER -out client.der

mv ca.crt ca.key ca/
mv server.crt server.key server/
mv client.crt client.key client/

mv ca.der server.der client.der certDER/

rm *.conf
rm *.req
rm *.srl 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98

將上述程式碼儲存為makefile.sh
做如下修改,終端執行。

- 修改 CN 域中 IP 地址為你主機/裝置的 IP 地址
- [可選]加密位數 1024 修改為你需要的加密位數

$ ./makefile.sh
  • 1

將會看到:
ssldir

ca目錄:儲存ca的私鑰ca.key和證書ca.crt
certDER目錄:將證書儲存為二進位制檔案 ca.der client.der server.der
client目錄: client.crt client.key
server目錄:server.crt server.key

3.2 刪除指令碼

刪除指令碼rmfile.sh:

rm ca/ -rf
rm certDER/ -rf
rm client/ -rf
rm server/ -rf
  • 1
  • 2
  • 3
  • 4

將上述程式碼儲存為rmfile.sh,終端執行,將會刪除產生過的目錄和檔案:

$./rmfile.sh
  • 1

3.3 CA校驗證書測試

我們可在本地使用 CA證書來分別校驗由自己頒發的伺服器證書 server.crt 和客戶端證書 client.crt .

$openssl verify -CAfile ca/ca.crt server/server.crt
  • 1
$openssl verify -CAfile ca/ca.crt client/client.crt
  • 1

verify