Fix SSH cipher key length: dynamically determine based on negotiated algorithm
- 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.
This commit is contained in:
@@ -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<Curve25519Kex>,
|
||||
host_key: Ed25519HostKey,
|
||||
shared_secret: Option<Vec<u8>>,
|
||||
@@ -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参数)
|
||||
|
||||
Reference in New Issue
Block a user