Verify key derivation is 100% correct
Breakthrough verification: - Python computed keys match server actual keys EXACTLY - Key derivation formula: HASH(K || H || X || session_id) verified - All keys (encryption, MAC, IV) derived correctly - Shared secret encoding (little-endian bytes) correct Remaining issue: - MAC verification fails despite correct key derivation - Client must be computing different keys than server - Need to compare client vs server actual key values Next step: Wireshark comparison of OpenSSH client keys
This commit is contained in:
@@ -75,15 +75,15 @@ impl SessionKeys {
|
|||||||
let session_id = exchange_hash.to_vec();
|
let session_id = exchange_hash.to_vec();
|
||||||
|
|
||||||
info!("SessionKeys::derive() starting");
|
info!("SessionKeys::derive() starting");
|
||||||
info!(" shared_secret ({} bytes): {:?}", shared_secret.len(), &shared_secret[..std::cmp::min(8, shared_secret.len())]);
|
info!(" shared_secret full (32 bytes): {:?}", shared_secret);
|
||||||
|
|
||||||
// RFC 8731 Section 3.1: X25519 output is little-endian
|
// RFC 8731 Section 3.1: X25519 output is little-endian
|
||||||
// OpenSSH sshbuf_put_bignum2_bytes() uses bytes DIRECTLY (no reversal)
|
// OpenSSH sshbuf_put_bignum2_bytes() uses bytes DIRECTLY (no reversal)
|
||||||
// Treats little-endian bytes as big-endian mpint (logical reinterpret)
|
// Treats little-endian bytes as big-endian mpint (logical reinterpret)
|
||||||
info!(" Using shared_secret directly (little-endian bytes as big-endian mpint)");
|
info!(" Using shared_secret directly (little-endian bytes as big-endian mpint)");
|
||||||
info!(" shared_secret[0] = {} (>=0x80? {})", shared_secret[0], shared_secret[0] >= 0x80);
|
info!(" shared_secret[0] = {} (>=0x80? {})", shared_secret[0], shared_secret[0] >= 0x80);
|
||||||
info!(" exchange_hash (H, {} bytes): {:?}", exchange_hash.len(), &exchange_hash[..8]);
|
info!(" exchange_hash full (32 bytes): {:?}", exchange_hash);
|
||||||
info!(" session_id ({} bytes): {:?}", session_id.len(), &session_id[..8]);
|
info!(" session_id full (32 bytes): {:?}", session_id);
|
||||||
|
|
||||||
// RFC 4253密钥派生公式:HASH(K || H || X || session_id)
|
// RFC 4253密钥派生公式:HASH(K || H || X || session_id)
|
||||||
// K is shared_secret encoded as mpint (using little-endian bytes directly)
|
// K is shared_secret encoded as mpint (using little-endian bytes directly)
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ impl KexExchangeHandler {
|
|||||||
|
|
||||||
info!("Exchange hash computed:");
|
info!("Exchange hash computed:");
|
||||||
info!(" shared_secret[0] = {} (>=0x80? {})", shared_secret[0], shared_secret[0] >= 0x80);
|
info!(" shared_secret[0] = {} (>=0x80? {})", shared_secret[0], shared_secret[0] >= 0x80);
|
||||||
info!(" exchange_hash (32 bytes): {:?}", &exchange_hash[..8]);
|
info!(" exchange_hash full (32 bytes): {:?}", exchange_hash);
|
||||||
|
|
||||||
self.exchange_hash = Some(exchange_hash.clone());
|
self.exchange_hash = Some(exchange_hash.clone());
|
||||||
info!("Exchange hash saved for key derivation");
|
info!("Exchange hash saved for key derivation");
|
||||||
|
|||||||
Reference in New Issue
Block a user