ssh 加密之前的过程

当tcp连接建立后,双方都要发送identification string,格式为:
SSH-protoversion-softwareversion SP comments CR LF

在发送完identification string之后,会进行 key exchange。

兼容性:
在ssh2.0之前的版本没有正式的文档。
old client, new server:
服务端应该有一个兼容选项的配置项,如果配置了,那么服务端发送的protoversion是1.99。对支持ssh2.0的客户端来说,1.99应该等于2.0。
new client, old server:
了解到服务端版本比较老之后,客户端应该重新建立连接,使用低版本信息。

binary packet:
uint32    packet_length
byte       padding_length
byte[n1]  payload; n1 = packet_length - padding_length - 1
byte[n2]  random padding; n2 = padding_length
byte[m]   mac (Message Authentication Code - MAC); m = mac_length

mac = MAC(key, sequence_number || unencrypted_packet)
sequence_number不传输,第一个包为0,以后每收到一个包,递增1。

各种密钥协商的过程:
client: 发送identity string,发送KEX_INIT包,其中包含COOKIE和支持的各种算法。
server: 收到identiy string,发送KEX_INIT包,其中包含COOKIE和支持的各种算法。
至此,双方知道所使用的算法。
使用serverVersion, clientVersion, 两个KEX_INIT包,初始化Kex。
client: 发送KEXDH_INIT或KEX_DH_GEX_REQUEST。
server: 发送KEXDH_REPLY或KEX_DH_GEX_GROUP,将DH的P和G发送给客户端。
client: 发送DH_GEX_INIT,其中包含客户端的DH公钥。
server: 发送DH_GEX_REPLY,其中包含公钥(HostKey),自己的DH公钥,以及签名算法和已知信息的签名。

密钥的计算:
client: 客户端发送NEWKEYS消息。
server: 
已知信息有:
V_C: 客户端的初始报文(包含版本信息的报文)。
V_S: 服务端的初始报文。
I_C:客户端的SSH_MSG_KEX_INIT的有效负荷。
I_S: 服务端的SSH_MSG_KEX_INIT的有效负荷。
e: 客户端DH公钥。
f: 服务端DH公钥。
K: DH计算的结果。

H=hash(V_C||V_S||I_C||I_S||K_S||e||f||K);
会话第一次秘钥交换生成的H才是session_id。
密钥计算公式:hash(K, H, 单个字符,session_id)
其中单个字符可以是如下几个字符:
'A': 用于计算客户端到服务端的IV。
'B': 用于计算服务端到客户端的IV。
'C': 用于计算客户端到服务端的加密秘钥。
'D': 用于计算服务端到客户端的加密秘钥。
'E': 用于计算客户端到服务端的HMAC秘钥。
'F': 用于计算服务端到客户端的HMAC秘钥。
计算的结果记为RE,如果想要的秘钥长度比RE长,RE=RE+hash(K, H, RE)。如果还不够,继续计算添加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值