SSH Padding计算修复:符合RFC 4253规范

修复内容:
- Padding计算逻辑完全符合SSH协议规范
- (packet_length + 4) % block_size == 0
- 最少4字节padding,动态调整满足block_size约束

测试结果:
 SSH服务器编译成功(0错误)
 SSH服务器启动成功(port 2024)
 SSH版本交换成功(SSH-2.0-MarkBaseSSH_1.0)
 SSH_MSG_KEXINIT发送和接收成功 
 OpenSSH客户端成功解析算法提议

OpenSSH客户端输出:
  debug1: SSH2_MSG_KEXINIT sent
  debug1: SSH2_MSG_KEXINIT received
  debug2: peer server KEXINIT proposal
  debug2: KEX algorithms: curve25519-sha256...

下一步:
- 测试SSH密钥交换(Curve25519)
- 测试认证流程
- 测试SFTP/SCP功能
This commit is contained in:
Warren
2026-06-10 15:43:31 +08:00
parent 9233b97214
commit 96bb08dd94

View File

@@ -67,27 +67,42 @@ pub struct SshPacket {
impl SshPacket {
/// 创建新的SSH packet
pub fn new(payload: Vec<u8>) -> Self {
// 计算paddingSSH协议要求packet总长度必须是block_size的倍数
// 参考OpenSSHblock_size = 8未加密阶段
let block_size = 8;
// 计算paddingSSH协议RFC 4253规范
// 参考OpenSSH packet.c: construct_packet()
let block_size = 8; // 未加密阶段block_size=8
// packet_length = padding_length + payload_length + 1 (type byte)
let payload_length = payload.len();
let min_padding = 4; // OpenSSH要求最少4字节padding
// 计算padding长度
let total_without_mac = 1 + payload_length; // padding_length byte + payload
let padding_needed = (block_size - (total_without_mac % block_size)) % block_size;
let padding_length = std::cmp::max(min_padding as u32, padding_needed as u32) as u8;
// SSH协议约束
// packet_length = padding_length + payload_length + 1
// (packet_length + 4) 必须是block_size的倍数
//
// 计算:
// (1 + payload_length + padding_length + 4) % 8 == 0
// => (5 + payload_length + padding_length) % 8 == 0
// 计算packet总长度
// 先尝试padding=4最小
let mut padding_length = min_padding as u8;
// 计算packet总长度包括4字节的packet_length字段
let packet_length = 1 + payload_length + padding_length as usize;
let total_length = packet_length + 4; // 加上packet_length字段本身的4字节
// 生成随机padding简化使用0实际应随机
// 如果总长度不是block_size的倍数增加padding
if total_length % block_size != 0 {
let remainder = total_length % block_size;
padding_length += (block_size - remainder) as u8;
}
// 重新计算packet_length
let packet_length = (1 + payload_length + padding_length as usize) as u32;
// 生成随机padding简化使用0
let padding = vec![0u8; padding_length as usize];
Self {
packet_length: packet_length as u32,
packet_length,
padding_length,
payload,
padding,