SSH传输层协议细节说明_apollobird

SSH传输层协议细节说明

2014-06-03 17:59阅读:

基于: RFC 4253:The Secure Shell (SSH) Transport Layer Protocol

以及openssh-5.3

RFC 4253描述了SSH2.0传输层协议的握手过程,但是在具体实现中还会遇到一些没有说明清楚的细节问题。对照openssh-5.3版本的源代码,列举一些实现SSH服务端/客户端时会遇到的陷阱和地雷,避免在今后研发中走弯路。

SSH传输层协议所处的位置如下图:

  X

在SSH传输层握手过程中,通讯过程如下图:

一些实现的细节问题:

(1)版本协商阶段的报文4-5即为计算唯一哈希标识H = HASH(V_C || V_S || I_C || I_S || K_S|| e || f || K) 中的V_C和V_S。但是在计算H的时候,是要去掉报文中最后的结束符\r\n的。例如对于客户端版本消息“SSH-2.0-OpenSSH_5.3\r\n“

计算H时只取

  (见前23个字节)

(2)大数的表示问题

Openssh使用openssl中的BIGNUM结构来表示和计算大数。在导出大数到buffer中时,必须要给最高位

加载中...

内容加载失败,点击此处重试

加载全文

为1的大数补充0x00前缀

比如对于下面的DH密钥交换的服务端公开参数f,其BIGNUM的首字节0xa4,最高位为1,则在使用该大数时(比如计算共享秘密值K时),必须补充前缀0x00

(3)算法协商SSH2_MSG_KEXINIT的问题

不同版本的openssh中支持的算法列表不同,排列的优先顺序也不同。就openssh-5.3版本而言,相比更高版本,它的列表中没有曲线密码算法;相比更低版本,它在密钥交换算法中优先了diffie-hellman-group-exchange-sha256,其摘要使用的是SHA-256。SHA-256的摘要长度为32字节,而低版本使用SHA-1,其摘要长度为20字节。

SSH2_MSG_KEXINIT消息6-7即为计算唯一哈希标识H = HASH(V_C || V_S || I_C || I_S ||K_S || e || f || K)中的I_C和I_S,但是在实现的细节上,并不是把这两个报文直接作为I_C和I_S,而是经过了如下处理:去掉了padding字节,去掉了padding长度,重新计算了packet_length字段。例如如下对于客户端算法协商消息

在计算H的时候I_C变为

比对可以看到,原始报文最末的8字节padding被去掉了,padding_length字节(第五个字节08)被去掉了,消息长度从16进制314变为了30b。

(4)KEXDH_GEX_REQUEST报文包含3个DH密钥交换参数Min、Numbers ofBits、Max,限定了DH选取大质数的长度,比如对于

min = 1024, nbits = 1024, max = 8192的报文

下面1024位的大质数是合格的(注意高位补0x00)

(5)KEXDH_GEX_REPLY报文包含3部分:服务端公钥、服务端DH公开数f和对唯一哈希标识H的签名。

其中服务端公钥部分根据不同非对称算法有所不同,对于rsa算法来说,包含3个参数:算法名称字符串、公开数publicExponent和modulus。

在计算H时,除了上面提到的对V_C、V_S、I_C、I_S的注意事项之外,还要注意:参数K_S是一个嵌套的Length-Value结构;参数K_S和参数e之间有DH密钥交换参数Min、Numbersof Bits、Max(这个和RFC标准中对H的计算公式有出入)。

(6)在握手阶段计算出的唯一哈希标识H被存为session_id,session_id不会被修改,只写入一次。后续重新协商密钥会改变H,但是session_id不变。(比如导出密钥时,计算HASH(K|| H || “A” ||session_id)。在首次握手时H=session_id,以后H可变,session_id不变。)

(7)服务端回复的KEXDH_GEX_REPLY可以与NEW_KEYS报文一起发送。WireShark解析有错误,比如

其实最后面16字节不是MAC,而是一个NEW_KEYS消息。

(8)在密钥交换过程中,客户端可以发出消息码对应为Ignore的消息。此时密钥交换过程与上述不同,4个报文简化为2个报文。两种过程的消息码在openssh中定义如下

#define SSH2_MSG_KEXDH_INIT 30

#define SSH2_MSG_KEXDH_REPLY 31

#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD 30

#define SSH2_MSG_KEX_DH_GEX_GROUP 31

#define SSH2_MSG_KEX_DH_GEX_INIT 32

#define SSH2_MSG_KEX_DH_GEX_REPLY 33

#define SSH2_MSG_KEX_DH_GEX_REQUEST 34

一般流程的密钥协商消息码走下面的31-34,客户端发出Ignore消息后,消息码走上面的30-31。

个人总结,欢迎交流讨论,请勿转载以讹传讹

分享

我的博客

微博

微信

朋友圈

1

N

同时转发到微博

发送


© 2024 实用范文网 | 联系我们: webmaster# 6400.net.cn