雷石 | SSH握手詳解

01.
什么是 SSH 握手?
Secure Shell (SSH) 是一種廣泛使用的傳輸層協(xié)議,用于保護(hù)客戶端和服務(wù)器之間的連接。SSH握手是SSH協(xié)議中的一個過程,負(fù)責(zé)協(xié)商初始信任因素,以便在SSH客戶端和SSH服務(wù)器之間建立安全通道以進(jìn)行 SSH連接。
握手過程包括:
1. SSH協(xié)議版本交換
2. 密鑰交換
3. 橢圓曲線 Diffie-Hellman初始化
4. 橢圓曲線 Diffie-Hellman回復(fù)
5. 新密鑰
02.
SSH版本交換
SSH首先由雙方向?qū)Ψ桨l(fā)送版本字符串。握手的這一部分并沒有發(fā)生什么特別的事情,但應(yīng)該注意的是,大多數(shù)相對現(xiàn)代的客戶端和服務(wù)器僅支持SSH 2.0,因為SSH1設(shè)計中存在幾個最明顯的缺陷:
-
SSH1是一種單一協(xié)議,無法自定義傳輸、身份驗證和連接問題。
-
SSH1使用較弱的CRC-32完整性檢查。
-
SSH1不支持單個會話內(nèi)的通道封裝。
03.
密鑰交換
客戶端和服務(wù)器使用SSH密鑰交換(有時稱為KEX)公開交換信息,從而產(chǎn)生客戶端和服務(wù)器共享的加密信息,觀察者無法從公共信息中發(fā)現(xiàn)或?qū)С鲈摷用苄畔ⅰ?br>
密鑰交換初始化
密鑰交換是由雙方向?qū)Ψ桨l(fā)送一條SSH_MSG_KEX_INIT消息來啟動的,其中包含他們支持的加密原語列表,其順序反映了他們的偏好。加密原語用于建立用于執(zhí)行密鑰交換和批量數(shù)據(jù)加密的構(gòu)建塊。
04.
橢圓曲線Diffie-Hellman 初始化
由于雙方使用相同的算法從支持的列表中選擇密碼原語,因此在密鑰交換初始化之后,可以立即開始密鑰交換。由于Teleport僅支持橢圓曲線Diffie-Hellman (ECDH),因此密鑰交換首先由客戶端生成臨時密鑰對(私有密鑰和關(guān)聯(lián)的公鑰)并將其公鑰在消息中發(fā)送給服務(wù)器SSH_MSG_KEX_ECDH_INIT 。
需要注意的是,這個密鑰對是短暫的:它只會在密鑰交換期間使用,并在之后被丟棄。這使得攻擊者被動記錄加密流量并希望在將來竊取私鑰的攻擊變得極其困難。竊取根本不存在的東西是非常困難的。該屬性稱為前向保密性。

05.
SSH橢圓曲線Diffie-Hellman 回復(fù)
服務(wù)器偵聽消息SSH_MSG_KEX_ECDH_INIT,并在收到消息后生成自己的臨時密鑰對。使用客戶端的公鑰和自己的密鑰對,服務(wù)器可以生成共享密鑰K 。
接下來,服務(wù)器生成稱為交換哈希H的內(nèi)容,并對其進(jìn)行簽名生成HS,交換哈希及其簽名有幾個用途:
-
由于交換哈希包含共享秘密,因此證明對方能夠生成共享秘密。
-
交換哈希和簽名的簽名/驗證循環(huán)允許客戶端驗證服務(wù)器擁有主機(jī)私鑰的所有權(quán),因此客戶端連接到正確的服務(wù)器(只要客 戶端可以信任相應(yīng)的公鑰,更多關(guān)于這個稍后再說)。
-
通過對交換哈希進(jìn)行簽名,而不是對交換哈希的輸入進(jìn)行簽名,要簽名的數(shù)據(jù)的大小將大大減少,并導(dǎo)致更快的握手。
交換哈希是通過以下字段的哈希( SHMagics M 、客戶端版本、服務(wù)器版本、客戶端SSH_MSG_KEXINIT消息、服務(wù)器SSH_MSG_KEXINIT消息。
-
Magics M 、客戶端版本、服務(wù)器版本、客戶端 SSH_MSG_KEXINIT 消息、服務(wù)器 SSH_MSG_KEXINIT 消息。
-
服務(wù)器主機(jī)公鑰(或證書)HPub 。該值(及其相應(yīng)的私鑰 HPiv)通常在進(jìn)程初始化期間生成,而不是在每次握手時生 成。
-
客戶端公鑰 A
-
服務(wù)器公鑰 B
-
共享密鑰 K
有了這些信息,SSH_MSG_KEX_ECDH_REPLY 服務(wù)器就可以根據(jù)服務(wù)器的臨時公鑰B 、服務(wù)器的主機(jī)公鑰 HPub以及交換哈希上的簽名來構(gòu)造消息 HS 。

一旦客戶端收到一個SSH_MSG_KEX_ECDH_REPLY ,它就擁有計算密鑰K和交換哈希所需的一切H 。
密鑰交換的最后一部分是客戶端從中提取主機(jī)公鑰(或證書)SSH_MSG_KEX_ECDH_REPLY 并驗證交換哈希的簽名,HS證明主機(jī)私鑰 的所有權(quán)。為了防止中間人 (MITM) 攻擊,一旦驗證了簽名,就會根據(jù)已知主機(jī)的本地數(shù)據(jù)庫檢查主機(jī)公鑰(或證書);如果此密鑰(或證書)不受信任,則連接將終止。
06.
新密鑰
在開始批量數(shù)據(jù)加密之前還有最后一件事,雙方都需要生成6個密鑰:兩個用于加密的密鑰、兩個初始化向量 (IV) 和兩個用于完整性的密鑰。那么問題來了,為什么要這么多密鑰?
加密密鑰用于確保數(shù)據(jù)機(jī)密性,并與對稱密碼一起使用來加密和解密數(shù)據(jù)。
完整性密鑰通常與消息身份驗證代碼 (MAC) 一起使用,以確保攻擊者不會操縱密文。如果不存在對密文的完整性檢查,則攻擊者可以 操縱通過線路發(fā)送的密文,并且可能會解密發(fā)件人未發(fā)送的內(nèi)容。
這種攻擊通常稱為Encrypt-then-MAC 。
初始化向量 (IV) 通常是用作對稱密碼輸入的隨機(jī)數(shù)。IV的目的是確保同一消息加密兩次不會產(chǎn)生相同的密文。
最后,為什么鑰匙是成對出現(xiàn)的?如果僅使用單個完整性密鑰,攻擊者就可以重放客戶端發(fā)送回客戶端的記錄,并且客戶端會認(rèn)為該記錄有效。使用多個完整性密鑰(一個用于服務(wù)器到客戶端,另一個用于客戶端到服務(wù)器),當(dāng)客戶端對密文執(zhí)行完整性檢查時,將會失敗。
接下來來了解下它們是如何生成的:
初始 IV 客戶端到服務(wù)器:
HASH(K || H || "A " ||session_id)
初始 IV 服務(wù)器到客戶端:
HASH(K || H || "B " || session_id)
客戶端到服務(wù)器的加密密鑰:
HASH(K || H || "C " || session_id)
加密密鑰服務(wù)器到客戶端:
HASH(K || H || "D " || session_id)
客戶端到服務(wù)器的完整性密鑰:
HASH(K || H || "E" || session_id)
服務(wù)器到客戶端的完整性密鑰:
HASH(K || H || "F" || session_id)
這里的哈希算法 SHA{256, 384, or 512} 取決于密鑰交換算法,并帶有 || 表示串聯(lián)的符號。
一旦計算出這些值,雙方都會送通知SSH_MSG_NEWKEYS另一方密鑰交換已結(jié)束,并且所有未來的通信都應(yīng)使用上面生成的新密鑰進(jìn)行。

此時,交換完成,就可以在客戶端和服務(wù)器之間建立可以提供機(jī)密性和完整性的安全通道。
杭州漠坦尼科技有限公司
商務(wù)咨詢:
0571-87031601
商務(wù)郵箱:
雷石安全實驗室
歡迎關(guān)注我們!
本文作者:m0sway
