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 sha2::Digest;
|
||||||
use std::io::{Read, Write};
|
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)
|
/// SSH密钥交换流程处理器(参考OpenSSH kex.c)
|
||||||
pub struct KexExchangeHandler {
|
pub struct KexExchangeHandler {
|
||||||
kex_algorithm: String,
|
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>,
|
server_kex: Option<Curve25519Kex>,
|
||||||
host_key: Ed25519HostKey,
|
host_key: Ed25519HostKey,
|
||||||
shared_secret: Option<Vec<u8>>,
|
shared_secret: Option<Vec<u8>>,
|
||||||
@@ -33,6 +49,8 @@ impl KexExchangeHandler {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
kex_algorithm: kex_result.kex_algorithm,
|
kex_algorithm: kex_result.kex_algorithm,
|
||||||
|
encryption_ctos: kex_result.encryption_ctos,
|
||||||
|
encryption_stoc: kex_result.encryption_stoc,
|
||||||
server_kex: None,
|
server_kex: None,
|
||||||
host_key,
|
host_key,
|
||||||
shared_secret: None,
|
shared_secret: None,
|
||||||
@@ -393,10 +411,9 @@ impl KexExchangeHandler {
|
|||||||
let client_public_key = self.client_public_key.as_ref().unwrap();
|
let client_public_key = self.client_public_key.as_ref().unwrap();
|
||||||
let host_key_blob = self.build_ssh_host_key()?;
|
let host_key_blob = self.build_ssh_host_key()?;
|
||||||
|
|
||||||
// ⭐ TODO: Get encryption algorithm from kex_result to determine cipher_key_len
|
// Determine cipher key length from negotiated encryption algorithm
|
||||||
// For now, hardcode 32 (AES-256) to maintain backward compatibility
|
let cipher_key_len = cipher_key_len(&self.encryption_stoc);
|
||||||
let cipher_key_len = 32;
|
info!("compute_session_keys: encryption_stoc={}, cipher_key_len={}", self.encryption_stoc, cipher_key_len);
|
||||||
info!("compute_session_keys: cipher_key_len={}", cipher_key_len);
|
|
||||||
SessionKeys::derive(
|
SessionKeys::derive(
|
||||||
shared_secret,
|
shared_secret,
|
||||||
exchange_hash, // 使用保存的exchange hash(H参数)
|
exchange_hash, // 使用保存的exchange hash(H参数)
|
||||||
|
|||||||
Reference in New Issue
Block a user