paramiko ssh 客户端主机密钥签名不匹配失败
paramiko ssh client failing in host key signature mismatch
我们有一个 SSH 服务器实现,我们正在使用 Paramiko 客户端来测试它在 diffie-hellman-group-exchange-shaX 的主机密钥签名不匹配方面始终失败。我已经找出签名不匹配的原因,但无法理解是哪一侧服务器或客户端做错了事。以下是不匹配的原因
1.Client 发送 "min || n || max" 到服务器。
2.Server找到最符合客户要求的组,发送
"p || g" 给客户。其中 p 是大素数,g 是生成器
现在问题发生在服务器发送大小大于 1 的生成器时,它以字节数组表示,前面有零加上它前面的长度为(大数字表示)
00 00 00 04 00 00 00 02
其中 04
是生成器长度,02
是它的值。用于主机密钥签名匹配的 H 使用完整的字节缓冲区用于散列的大数字。 H表示为
H = hash(V_C
|| V_S || I_C || I_S || K_S || min || n || max || p || g || e ||
f || K)
现在,当 paramiko 存储生成器时,它会删除前面的零并且不存储长度。
它将 g 转换回字节,并使用 len(g) 将字节缩小的 g 的长度放在前面进行哈希处理
使用以下例程。
def add_string(self, s):
"""
Add a string to the stream.
:param str s: string to add
"""
s = asbytes(s)
self.add_size(len(s))
self.packet.write(s)
这只是一个字节,所以我们实际上对 g 字节缓冲区进行哈希处理的内容如下
00 00 00 01 02
其中 01 是字符串长度,02 是与服务器 g 缓冲区不同的值,因此签名不匹配
所以我的问题是哪一侧错误地表示了 big nums 的字节缓冲区?
根据 RFC4251:
Blockquote
mpint
Represents multiple precision integers in two's complement format,
stored as a string, 8 bits per byte, MSB first. Negative numbers
have the value 1 as the most significant bit of the first byte of
the data partition. If the most significant bit would be set for
a positive number, the number MUST be preceded by a zero byte.
Unnecessary leading bytes with the value 0 or 255 MUST NOT be
included. The value zero MUST be stored as a string with zero
bytes of data.
eg: 80(hex) 00 00 00 02 00 80
因此服务器的操作是错误的,paramiko 删除前面的填充零是正确的。
我们有一个 SSH 服务器实现,我们正在使用 Paramiko 客户端来测试它在 diffie-hellman-group-exchange-shaX 的主机密钥签名不匹配方面始终失败。我已经找出签名不匹配的原因,但无法理解是哪一侧服务器或客户端做错了事。以下是不匹配的原因
1.Client 发送 "min || n || max" 到服务器。
2.Server找到最符合客户要求的组,发送 "p || g" 给客户。其中 p 是大素数,g 是生成器 现在问题发生在服务器发送大小大于 1 的生成器时,它以字节数组表示,前面有零加上它前面的长度为(大数字表示)
00 00 00 04 00 00 00 02
其中 04
是生成器长度,02
是它的值。用于主机密钥签名匹配的 H 使用完整的字节缓冲区用于散列的大数字。 H表示为
H = hash(V_C
|| V_S || I_C || I_S || K_S || min || n || max || p || g || e ||
f || K)
现在,当 paramiko 存储生成器时,它会删除前面的零并且不存储长度。
它将 g 转换回字节,并使用 len(g) 将字节缩小的 g 的长度放在前面进行哈希处理
使用以下例程。
def add_string(self, s):
"""
Add a string to the stream.
:param str s: string to add
"""
s = asbytes(s)
self.add_size(len(s))
self.packet.write(s)
这只是一个字节,所以我们实际上对 g 字节缓冲区进行哈希处理的内容如下
00 00 00 01 02
其中 01 是字符串长度,02 是与服务器 g 缓冲区不同的值,因此签名不匹配
所以我的问题是哪一侧错误地表示了 big nums 的字节缓冲区?
根据 RFC4251:
Blockquote
mpint
Represents multiple precision integers in two's complement format,
stored as a string, 8 bits per byte, MSB first. Negative numbers
have the value 1 as the most significant bit of the first byte of
the data partition. If the most significant bit would be set for
a positive number, the number MUST be preceded by a zero byte.
Unnecessary leading bytes with the value 0 or 255 MUST NOT be
included. The value zero MUST be stored as a string with zero
bytes of data.
eg: 80(hex) 00 00 00 02 00 80
因此服务器的操作是错误的,paramiko 删除前面的填充零是正确的。