From c91dbe2cc3a2625a24780f49e537dafeb18e33cd Mon Sep 17 00:00:00 2001 From: Warren Date: Sat, 20 Jun 2026 21:16:25 +0800 Subject: [PATCH] Fix SSH cipher key length: dynamically determine based on negotiated algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add cipher_key_len() helper function - Store encryption_ctos/stoc in KexExchangeHandler - Use algorithm name to determine key_len (aes256 → 32, aes128 → 16) - Remove hardcoded cipher_key_len=32 TODO All 229 tests pass. --- markbase-core/src/ssh_server/kex_exchange.rs | 25 ++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/markbase-core/src/ssh_server/kex_exchange.rs b/markbase-core/src/ssh_server/kex_exchange.rs index 2a9cdbc..683bf87 100644 --- a/markbase-core/src/ssh_server/kex_exchange.rs +++ b/markbase-core/src/ssh_server/kex_exchange.rs @@ -10,9 +10,25 @@ use log::info; use sha2::Digest; use std::io::{Read, Write}; +/// Determine cipher key length from encryption algorithm name +/// Reference: OpenSSH cipher.c, RFC 4253 +fn cipher_key_len(algorithm: &str) -> usize { + if algorithm.contains("aes256") || algorithm.contains("aes256-gcm") { + 32 + } else if algorithm.contains("aes128") || algorithm.contains("aes128-ctr") { + 16 + } else { + // Default to AES-256 for unknown algorithms + info!("Unknown encryption algorithm '{}', using default key_len=32", algorithm); + 32 + } +} + /// SSH密钥交换流程处理器(参考OpenSSH kex.c) pub struct KexExchangeHandler { kex_algorithm: String, + encryption_ctos: String, // Phase fix: store encryption algorithm for key length + encryption_stoc: String, // Phase fix: store encryption algorithm for key length server_kex: Option, host_key: Ed25519HostKey, shared_secret: Option>, @@ -33,6 +49,8 @@ impl KexExchangeHandler { Ok(Self { kex_algorithm: kex_result.kex_algorithm, + encryption_ctos: kex_result.encryption_ctos, + encryption_stoc: kex_result.encryption_stoc, server_kex: None, host_key, shared_secret: None, @@ -393,10 +411,9 @@ impl KexExchangeHandler { let client_public_key = self.client_public_key.as_ref().unwrap(); let host_key_blob = self.build_ssh_host_key()?; - // ⭐ TODO: Get encryption algorithm from kex_result to determine cipher_key_len - // For now, hardcode 32 (AES-256) to maintain backward compatibility - let cipher_key_len = 32; - info!("compute_session_keys: cipher_key_len={}", cipher_key_len); + // Determine cipher key length from negotiated encryption algorithm + let cipher_key_len = cipher_key_len(&self.encryption_stoc); + info!("compute_session_keys: encryption_stoc={}, cipher_key_len={}", self.encryption_stoc, cipher_key_len); SessionKeys::derive( shared_secret, exchange_hash, // 使用保存的exchange hash(H参数)