feat(ssh): implement session key derivation
SSH会话密钥实现完成: 实现内容: 1. KexExchangeHandler保存shared_secret和public_keys - shared_secret字段(Option<Vec<u8>>) - client_public_key字段 - server_public_key字段 2. compute_session_keys()方法实现 - 从保存的shared_secret计算会话密钥 - 使用SessionKeys::derive()方法 - 返回真实SessionKeys(而非临时默认密钥) 3. server.rs使用真实会话密钥 - perform_complete_kex_exchange调用compute_session_keys() - EncryptionContext::from_session_keys() - 初始化真实加密上下文 测试结果: - ✅ Connection established - ✅ SSH2_MSG_KEX_ECDH_REPLY received(签名验证成功) - ✅ SSH2_MSG_NEWKEYS sent/received(加密通道建立) - 🆕 SSH_MSG_SERVICE_REQUEST sent(客户端尝试认证) - ❌ Connection reset(服务器无法处理加密packet) 进展对比: - 之前:Bad packet length错误 - 现在:客户端成功发送SERVICE_REQUEST,连接重置 下一步: - perform_ssh_auth()使用EncryptedPacket - 实现EncryptedPacket::read() - 完成加密packet处理
This commit is contained in:
@@ -15,6 +15,9 @@ pub struct KexExchangeHandler {
|
||||
kex_algorithm: String,
|
||||
server_kex: Option<Curve25519Kex>,
|
||||
host_key: Ed25519HostKey,
|
||||
shared_secret: Option<Vec<u8>>,
|
||||
client_public_key: Option<Vec<u8>>,
|
||||
server_public_key: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl KexExchangeHandler {
|
||||
@@ -27,6 +30,9 @@ impl KexExchangeHandler {
|
||||
kex_algorithm: kex_result.kex_algorithm,
|
||||
server_kex: None,
|
||||
host_key,
|
||||
shared_secret: None,
|
||||
client_public_key: None,
|
||||
server_public_key: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -200,20 +206,26 @@ impl KexExchangeHandler {
|
||||
}
|
||||
|
||||
/// 计算会话密钥(参考OpenSSH kex.c: derive_keys())
|
||||
pub fn compute_session_keys(&self, shared_secret: &[u8]) -> Result<SessionKeys> {
|
||||
if self.server_kex.is_none() {
|
||||
return Err(anyhow!("No KEX exchange performed"));
|
||||
pub fn compute_session_keys(&self) -> Result<SessionKeys> {
|
||||
if self.shared_secret.is_none() {
|
||||
return Err(anyhow!("No shared secret available"));
|
||||
}
|
||||
|
||||
// 参考OpenSSH kex.c: kex_derive_keys()
|
||||
// 简化实现:实际需要更多参数
|
||||
if self.server_public_key.is_none() || self.client_public_key.is_none() {
|
||||
return Err(anyhow!("Missing public keys"));
|
||||
}
|
||||
|
||||
let shared_secret = self.shared_secret.as_ref().unwrap();
|
||||
let server_public_key = self.server_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()?;
|
||||
|
||||
SessionKeys::derive(
|
||||
shared_secret,
|
||||
"SHA256", // curve25519-sha256
|
||||
self.server_kex.as_ref().unwrap().public_key(),
|
||||
&[], // client public key(实际应传入)
|
||||
&self.build_ssh_host_key()?,
|
||||
"SHA256",
|
||||
server_public_key,
|
||||
client_public_key,
|
||||
&host_key_blob,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,10 @@ fn perform_complete_kex_exchange(
|
||||
return Err(anyhow::anyhow!("Encryption channel not ready"));
|
||||
}
|
||||
|
||||
Ok(EncryptionContext::default())
|
||||
let session_keys = kex_state.exchange_handler.compute_session_keys()?;
|
||||
let encryption_ctx = EncryptionContext::from_session_keys(&session_keys);
|
||||
|
||||
Ok(encryption_ctx)
|
||||
}
|
||||
|
||||
/// SSH认证流程(Phase 5)
|
||||
|
||||
Reference in New Issue
Block a user