雷石 | SSH握手详解
共 3434字,需浏览 7分钟
·
2024-04-11 09:32
01.
什么是 SSH 握手?
Secure Shell (SSH) 是一种广泛使用的传输层协议,用于保护客户端和服务器之间的连接。SSH握手是SSH协议中的一个过程,负责协商初始信任因素,以便在SSH客户端和SSH服务器之间建立安全通道以进行 SSH连接。
握手过程包括:
1. SSH协议版本交换
2. 密钥交换
3. 椭圆曲线 Diffie-Hellman初始化
4. 椭圆曲线 Diffie-Hellman回复
5. 新密钥
02.
SSH版本交换
SSH首先由双方向对方发送版本字符串。握手的这一部分并没有发生什么特别的事情,但应该注意的是,大多数相对现代的客户端和服务器仅支持SSH 2.0,因为SSH1设计中存在几个最明显的缺陷:
-
SSH1是一种单一协议,无法自定义传输、身份验证和连接问题。
-
SSH1使用较弱的CRC-32完整性检查。
-
SSH1不支持单个会话内的通道封装。
03.
密钥交换
客户端和服务器使用SSH密钥交换(有时称为KEX)公开交换信息,从而产生客户端和服务器共享的加密信息,观察者无法从公共信息中发现或导出该加密信息。
密钥交换初始化
密钥交换是由双方向对方发送一条SSH_MSG_KEX_INIT消息来启动的,其中包含他们支持的加密原语列表,其顺序反映了他们的偏好。加密原语用于建立用于执行密钥交换和批量数据加密的构建块。
04.
椭圆曲线Diffie-Hellman 初始化
由于双方使用相同的算法从支持的列表中选择密码原语,因此在密钥交换初始化之后,可以立即开始密钥交换。由于Teleport仅支持椭圆曲线Diffie-Hellman (ECDH),因此密钥交换首先由客户端生成临时密钥对(私有密钥和关联的公钥)并将其公钥在消息中发送给服务器SSH_MSG_KEX_ECDH_INIT 。
需要注意的是,这个密钥对是短暂的:它只会在密钥交换期间使用,并在之后被丢弃。这使得攻击者被动记录加密流量并希望在将来窃取私钥的攻击变得极其困难。窃取根本不存在的东西是非常困难的。该属性称为前向保密性。
05.
SSH椭圆曲线Diffie-Hellman 回复
服务器侦听消息SSH_MSG_KEX_ECDH_INIT,并在收到消息后生成自己的临时密钥对。使用客户端的公钥和自己的密钥对,服务器可以生成共享密钥K 。
接下来,服务器生成称为交换哈希H的内容,并对其进行签名生成HS,交换哈希及其签名有几个用途:
-
由于交换哈希包含共享秘密,因此证明对方能够生成共享秘密。
-
交换哈希和签名的签名/验证循环允许客户端验证服务器拥有主机私钥的所有权,因此客户端连接到正确的服务器(只要客 户端可以信任相应的公钥,更多关于这个稍后再说)。
-
通过对交换哈希进行签名,而不是对交换哈希的输入进行签名,要签名的数据的大小将大大减少,并导致更快的握手。
交换哈希是通过以下字段的哈希( SHMagics M 、客户端版本、服务器版本、客户端SSH_MSG_KEXINIT消息、服务器SSH_MSG_KEXINIT消息。
-
Magics M 、客户端版本、服务器版本、客户端 SSH_MSG_KEXINIT 消息、服务器 SSH_MSG_KEXINIT 消息。
-
服务器主机公钥(或证书)HPub 。该值(及其相应的私钥 HPiv)通常在进程初始化期间生成,而不是在每次握手时生 成。
-
客户端公钥 A
-
服务器公钥 B
-
共享密钥 K
有了这些信息,SSH_MSG_KEX_ECDH_REPLY 服务器就可以根据服务器的临时公钥B 、服务器的主机公钥 HPub以及交换哈希上的签名来构造消息 HS 。
一旦客户端收到一个SSH_MSG_KEX_ECDH_REPLY ,它就拥有计算密钥K和交换哈希所需的一切H 。
密钥交换的最后一部分是客户端从中提取主机公钥(或证书)SSH_MSG_KEX_ECDH_REPLY 并验证交换哈希的签名,HS证明主机私钥 的所有权。为了防止中间人 (MITM) 攻击,一旦验证了签名,就会根据已知主机的本地数据库检查主机公钥(或证书);如果此密钥(或证书)不受信任,则连接将终止。
06.
新密钥
在开始批量数据加密之前还有最后一件事,双方都需要生成6个密钥:两个用于加密的密钥、两个初始化向量 (IV) 和两个用于完整性的密钥。那么问题来了,为什么要这么多密钥?
加密密钥用于确保数据机密性,并与对称密码一起使用来加密和解密数据。
完整性密钥通常与消息身份验证代码 (MAC) 一起使用,以确保攻击者不会操纵密文。如果不存在对密文的完整性检查,则攻击者可以 操纵通过线路发送的密文,并且可能会解密发件人未发送的内容。
这种攻击通常称为Encrypt-then-MAC 。
初始化向量 (IV) 通常是用作对称密码输入的随机数。IV的目的是确保同一消息加密两次不会产生相同的密文。
最后,为什么钥匙是成对出现的?如果仅使用单个完整性密钥,攻击者就可以重放客户端发送回客户端的记录,并且客户端会认为该记录有效。使用多个完整性密钥(一个用于服务器到客户端,另一个用于客户端到服务器),当客户端对密文执行完整性检查时,将会失败。
接下来来了解下它们是如何生成的:
初始 IV 客户端到服务器:
HASH(K || H || "A " ||session_id)
初始 IV 服务器到客户端:
HASH(K || H || "B " || session_id)
客户端到服务器的加密密钥:
HASH(K || H || "C " || session_id)
加密密钥服务器到客户端:
HASH(K || H || "D " || session_id)
客户端到服务器的完整性密钥:
HASH(K || H || "E" || session_id)
服务器到客户端的完整性密钥:
HASH(K || H || "F" || session_id)
这里的哈希算法 SHA{256, 384, or 512} 取决于密钥交换算法,并带有 || 表示串联的符号。
一旦计算出这些值,双方都会送通知SSH_MSG_NEWKEYS另一方密钥交换已结束,并且所有未来的通信都应使用上面生成的新密钥进行。
此时,交换完成,就可以在客户端和服务器之间建立可以提供机密性和完整性的安全通道。
杭州漠坦尼科技有限公司
商务咨询:
0571-87031601
商务邮箱:
mtn@motanni.com
雷石安全实验室
欢迎关注我们!
本文作者:m0sway