OpenSSH client源码验证:发现padding bytes差异
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

深度分析OpenSSH packet processing:

关键发现:
 ssh_packet_read_poll2_mux(): incoming_packet存储padding_length + type + payload + padding
 sshbuf_get_u8()消耗padding_length和type后,剩余payload + padding
 kex_input_kexinit(): sshpkt_ptr()返回payload + padding(从cookie开始)
 kex->peer存储:payload fields + padding(不包括type byte)

差异:
- OpenSSH kex->peer包括padding bytes
- 我们client_kexinit_payload不包括padding bytes

测试padding fix:
 加padding后:签名验证失败(说明exchange hash计算方式不同)
 不加padding:签名成功但MAC失败(说明不是padding问题)

结论:
OpenSSH exchange hash calculation可能不包括padding bytes
需要进一步验证OpenSSH如何计算exchange hash

下一步建议:
1. 检查OpenSSH exchange hash calculation是否重新构建packet(包括padding)
2. 或验证OpenSSH kex->my是否也包括padding
3. 或使用OpenSSH server对比测试(手动启动)
This commit is contained in:
Warren
2026-06-15 01:42:28 +08:00
parent 7a7030a65f
commit 581c78469c
2 changed files with 16 additions and 0 deletions

Binary file not shown.

View File

@@ -44,13 +44,29 @@ impl KexState {
}
/// 保存KEXINIT payloads用于Exchange Hash计算
///
/// 分析OpenSSH源码后的结论
/// - kex->peer存储的是incoming_packet剩余内容payload fields + padding
/// - kex->my存储的是prop2buf()结果payload fields不包括padding
///
/// **但exchange hash必须使用相同的I_C/I_S**
///
/// 疑问OpenSSH如何确保client和server使用相同的padding
/// 可能答案OpenSSH在计算exchange hash时不包括padding
///
/// 暂时保持不包括padding因为签名验证之前成功
pub fn save_kexinit_payloads(
&mut self,
client_kexinit: &SshPacket,
server_kexinit: &SshPacket,
) {
// Only save payload (without padding) for now
self.client_kexinit_payload = client_kexinit.payload.clone();
self.server_kexinit_payload = server_kexinit.payload.clone();
info!("Saved KEXINIT payloads (payload only, no padding)");
info!(" client payload: {} bytes", self.client_kexinit_payload.len());
info!(" server payload: {} bytes", self.server_kexinit_payload.len());
}
/// 计算Exchange Hash参考OpenSSH kex.c: kex_hash()