共計(jì) 3307 個(gè)字符,預(yù)計(jì)需要花費(fèi) 9 分鐘才能閱讀完成。
怎么進(jìn)行 Server Name Indication 的理論分析,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面丸趣 TV 小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
SNI (Server Name Indication)是用來改善服務(wù)器與客戶端 SSL (Secure Socket Layer)和 TLS (Transport Layer Security) 的一個(gè)擴(kuò)展。主要解決一臺服務(wù)器只能使用一個(gè)證書 (一個(gè)域名) 的缺點(diǎn),隨著服務(wù)器對虛擬主機(jī)的支持,一個(gè)服務(wù)器上可以為多個(gè)域名提供服務(wù),因此 SNI 必須得到支持才能滿足需求。
SNI 產(chǎn)生背景
SSL 以及 TLS(SSL 的升級版)為客戶端與服務(wù)器端進(jìn)行安全連接提供了條件。但是,由于當(dāng)時(shí)技術(shù)限制,SSL 初期的設(shè)計(jì)順應(yīng)經(jīng)典的公鑰基礎(chǔ)設(shè)施 PKI(Public Key Infrastructure)設(shè)計(jì),PKI 認(rèn)為一個(gè)服務(wù)器只為一個(gè)域名提供服務(wù),從而一個(gè)服務(wù)器上也就只能使用一個(gè)證書。這樣客戶端在發(fā)送請求的時(shí)候,利用 DNS 域名解析,只要向解析到的 IP 地址(服務(wù)器地址)發(fā)送請求,然后服務(wù)器將自身唯一的證書返回回來,交給客戶端驗(yàn)證,驗(yàn)證通過,則繼續(xù)進(jìn)行后續(xù)通信。然后通過協(xié)商好的加密通道,獲得所需要的內(nèi)容。這意味著服務(wù)器可以在 SSL 的啟動(dòng)動(dòng)階段發(fā)送或提交證書,因?yàn)樗浪跒槟膫€(gè)特定的域名服務(wù)。
隨著 HTTP 服務(wù)器開啟虛擬主機(jī)支持后,每個(gè)服務(wù)器通過相同的 IP 地址可以為很多域名提供服務(wù)。這種為虛擬主機(jī)提供通信安全的簡單途徑,卻經(jīng)常導(dǎo)致使用了錯(cuò)誤的數(shù)字證書,因?yàn)榉?wù)器端無法知道客戶端到底請求的是哪個(gè)域名下的服務(wù),從而導(dǎo)致瀏覽器對用戶發(fā)出警告。
不幸的是,當(dāng)設(shè)置了 SSL 加密,服務(wù)器在讀取 HTTP 請求里面的域名之前已經(jīng)向客戶端提交了證書,也就是已經(jīng)為默認(rèn)域提供了服務(wù)。但是,一個(gè)服務(wù)器可能為上千個(gè)域名提供服務(wù),不可能將所有證書都發(fā)送給客戶端,讓客戶端一一驗(yàn)證,找到與請求域名對應(yīng)的證書。SNI 的設(shè)計(jì)目的是為了讓服務(wù)器根據(jù)請求來決定為哪個(gè)域服務(wù),這個(gè)信息通常從 HTTP 請求頭獲得。
SSL/TLS 握手
熟悉 SSL/TLS 握手過程的都知道,主要經(jīng)過以下幾個(gè)過程:
基于 RSA 握手和密鑰交換的客戶端驗(yàn)證服務(wù)器為示例詳解 TLS/SSL 握手過程。
1 C- S:client_hello
客戶端發(fā)起請求,以明文傳輸請求信息,包含版本信息,加密套件候選列表,壓縮算法候選列表,隨機(jī)數(shù),擴(kuò)展字段等信息。
SSL/STL 版本支持的最高 TSL 協(xié)議版本 version,從低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,當(dāng)前基本不再使用低于 TLSv1 的版本;
客戶端支持的加密套件 cipher suites 列表,每個(gè)加密套件對應(yīng)前面 TLS 原理中的四個(gè)功能的組合:認(rèn)證算法 Au (身份驗(yàn)證)、密鑰交換算法 KeyExchange(密鑰協(xié)商)、對稱加密算法 Enc (信息加密)和信息摘要 Mac(完整性校驗(yàn));
支持的壓縮算法 compression methods 列表,用于后續(xù)的信息壓縮傳輸;
隨機(jī)數(shù) random_C,用于后續(xù)的密鑰的生成;
擴(kuò)展字段 extensions,支持協(xié)議與算法的相關(guān)參數(shù)以及其它輔助信息等,常見的 SNI 就屬于擴(kuò)展字段,后續(xù)單獨(dú)討論該字段作用。
2 server_hello+server_certificate+sever_hello_done
server_hello, 服務(wù)端返回協(xié)商的信息結(jié)果,包括選擇使用的協(xié)議版本 version,選擇的加密套件 cipher suite,選擇的壓縮算法 compression method、隨機(jī)數(shù) random_S 等,其中隨機(jī)數(shù)用于后續(xù)的密鑰協(xié)商;
server_certificates, 服務(wù)器端配置對應(yīng)的證書鏈,用于身份驗(yàn)證與密鑰交換;
server_hello_done,通知客戶端 server_hello 信息發(fā)送結(jié)束;
3 證書校驗(yàn)
客戶端驗(yàn)證證書的合法性,如果驗(yàn)證通過才會進(jìn)行后續(xù)通信,否則根據(jù)錯(cuò)誤情況不同做出提示和操作,合法性驗(yàn)證包括如下:
證書鏈的可信性 trusted certificate path,方法如前文所述;
證書是否吊銷 revocation,有兩類方式離線 CRL 與在線 OCSP,不同的客戶端行為會不同;
有效期 expiry date,證書是否在有效時(shí)間范圍;
域名 domain,核查證書域名是否與當(dāng)前的訪問域名匹配,匹配規(guī)則后續(xù)分析;
4 client_key_exchange+change_cipher_spec+encrypted_handshake_message
client_key_exchange,合法性驗(yàn)證通過之后,客戶端計(jì)算產(chǎn)生隨機(jī)數(shù)字 Pre-master,并用證書公鑰加密,發(fā)送給服務(wù)器;
此時(shí)客戶端已經(jīng)獲取全部的計(jì)算協(xié)商密鑰需要的信息:兩個(gè)明文隨機(jī)數(shù) random_C 和 random_S 與自己計(jì)算產(chǎn)生的 Pre-master,計(jì)算得到協(xié)商密鑰;
enc_key=Fuc(random_C, random_S, Pre-Master)
change_cipher_spec,客戶端通知服務(wù)器后續(xù)的通信都采用協(xié)商的通信密鑰和加密算法進(jìn)行加密通信;
encrypted_handshake_message,結(jié)合之前所有通信參數(shù)的 hash 值與其它相關(guān)信息生成一段數(shù)據(jù),采用協(xié)商密鑰 session secret 與算法進(jìn)行加密,然后發(fā)送給服務(wù)器用于數(shù)據(jù)與握手驗(yàn)證;
5 change_cipher_spec+encrypted_handshake_message
服務(wù)器用私鑰解密加密的 Pre-master 數(shù)據(jù),基于之前交換的兩個(gè)明文隨機(jī)數(shù) random_C 和 random_S,計(jì)算得到協(xié)商密鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
計(jì)算之前所有接收信息的 hash 值,然后解密客戶端發(fā)送的 encrypted_handshake_message,驗(yàn)證數(shù)據(jù)和密鑰正確性;
change_cipher_spec, 驗(yàn)證通過之后,服務(wù)器同樣發(fā)送 change_cipher_spec 以告知客戶端后續(xù)的通信都采用協(xié)商的密鑰與算法進(jìn)行加密通信;
encrypted_handshake_message, 服務(wù)器也結(jié)合所有當(dāng)前的通信參數(shù)信息生成一段數(shù)據(jù)并采用協(xié)商密鑰 session secret 與算法加密并發(fā)送到客戶端;
6 握手結(jié)束
客戶端計(jì)算所有接收信息的 hash 值,并采用協(xié)商密鑰解密 encrypted_handshake_message,驗(yàn)證服務(wù)器發(fā)送的數(shù)據(jù)和密鑰,驗(yàn)證通過則握手完成;
7 加密通信
開始使用協(xié)商密鑰與算法進(jìn)行加密通信。
由以上過程可以知道,沒有 SNI 的情況下,服務(wù)器無法預(yù)知客戶端到底請求的是哪一個(gè)域名的服務(wù)。
SNI 應(yīng)用
SNI 的 TLS 擴(kuò)展通過發(fā)送虛擬域的名字做為 TSL 協(xié)商的一部分修正了這個(gè)問題,在 Client Hello 階段,通過 SNI 擴(kuò)展,將域名信息提前告訴服務(wù)器,服務(wù)器根據(jù)域名取得對應(yīng)的證書返回給客戶端已完成校驗(yàn)過程。
curl
Linux 中主要的網(wǎng)絡(luò)交互工具,curl 7.18.1+ openssl 0.9.8j+ 可以支持 SNI,CentOS6.5 及以下都是 curl 7.15 不支持 SNI,curl 7.21.3 又支持了–resolve 參數(shù),可以直接定位到 IP 地址進(jìn)行訪問,對于一個(gè)域名有多個(gè)部署節(jié)點(diǎn)的服務(wù)來說,這個(gè)參數(shù)可以定向的訪問某個(gè)設(shè)備。基本語法為:
Example:
curl -k -I --resolve www.example.com:80:192.0.2.1 https://www.example.com/index.html
WireShark 抓包驗(yàn)證 SNI
使用 curl7.15(不支持 SNI)抓包結(jié)果:
可以看到,使用 curl7.15 抓包得到的數(shù)據(jù)無 SNI 擴(kuò)展,而是用 curl7.43 抓包得到的數(shù)據(jù),包含 SNI 擴(kuò)展,其中包含 host 信息。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注丸趣 TV 行業(yè)資訊頻道,感謝您對丸趣 TV 的支持。