为什么在密钥协商时首选密码、mac 和压缩被写入两次?
Why preferred ciphers, macs and compression are written twice while key negotiations?
我正在尝试了解 SSH 协议的客户端部分并参考 Paramiko library which is a native Python library for SSH protocol. The corresponding code can be found here。
def _send_kex_init(self):
"""
announce to the other side that we'd like to negotiate keys, and what
kind of key negotiation we support.
"""
self.clear_to_send_lock.acquire()
try:
self.clear_to_send.clear()
finally:
self.clear_to_send_lock.release()
self.in_kex = True
if self.server_mode:
mp_required_prefix = 'diffie-hellman-group-exchange-sha'
kex_mp = [k for k in self._preferred_kex if k.startswith(mp_required_prefix)]
if (self._modulus_pack is None) and (len(kex_mp) > 0):
# can't do group-exchange if we don't have a pack of potential primes
pkex = [k for k in self.get_security_options().kex
if not k.startswith(mp_required_prefix)]
self.get_security_options().kex = pkex
available_server_keys = list(filter(list(self.server_key_dict.keys()).__contains__,
self._preferred_keys))
else:
available_server_keys = self._preferred_keys
m = Message()
m.add_byte(cMSG_KEXINIT)
m.add_bytes(os.urandom(16))
m.add_list(self._preferred_kex)
m.add_list(available_server_keys)
m.add_list(self._preferred_ciphers)
m.add_list(self._preferred_ciphers)
m.add_list(self._preferred_macs)
m.add_list(self._preferred_macs)
m.add_list(self._preferred_compression)
m.add_list(self._preferred_compression)
m.add_string(bytes())
m.add_string(bytes())
m.add_boolean(False)
m.add_int(0)
# save a copy for later (needed to compute a hash)
self.local_kex_init = m.asbytes()
self._send_message(m)
SSH 协议允许双方对传入和传出方向实施不同的算法集。或者实际上,它允许一方仅针对其中一个方向实施特定算法。
Paramiko 实现了双向的所有算法,因此它使用相同的集合填充传入和传出算法的列表。
参见_parse_kex_init
方法中的代码,它解析由您引用的代码填充的数据包:
client_encrypt_algo_list = m.get_list()
server_encrypt_algo_list = m.get_list()
...
agreed_local_ciphers = list(
filter(
client_encrypt_algo_list.__contains__,
self._preferred_ciphers,
)
)
agreed_remote_ciphers = list(
filter(
server_encrypt_algo_list.__contains__,
self._preferred_ciphers,
)
)
我正在尝试了解 SSH 协议的客户端部分并参考 Paramiko library which is a native Python library for SSH protocol. The corresponding code can be found here。
def _send_kex_init(self):
"""
announce to the other side that we'd like to negotiate keys, and what
kind of key negotiation we support.
"""
self.clear_to_send_lock.acquire()
try:
self.clear_to_send.clear()
finally:
self.clear_to_send_lock.release()
self.in_kex = True
if self.server_mode:
mp_required_prefix = 'diffie-hellman-group-exchange-sha'
kex_mp = [k for k in self._preferred_kex if k.startswith(mp_required_prefix)]
if (self._modulus_pack is None) and (len(kex_mp) > 0):
# can't do group-exchange if we don't have a pack of potential primes
pkex = [k for k in self.get_security_options().kex
if not k.startswith(mp_required_prefix)]
self.get_security_options().kex = pkex
available_server_keys = list(filter(list(self.server_key_dict.keys()).__contains__,
self._preferred_keys))
else:
available_server_keys = self._preferred_keys
m = Message()
m.add_byte(cMSG_KEXINIT)
m.add_bytes(os.urandom(16))
m.add_list(self._preferred_kex)
m.add_list(available_server_keys)
m.add_list(self._preferred_ciphers)
m.add_list(self._preferred_ciphers)
m.add_list(self._preferred_macs)
m.add_list(self._preferred_macs)
m.add_list(self._preferred_compression)
m.add_list(self._preferred_compression)
m.add_string(bytes())
m.add_string(bytes())
m.add_boolean(False)
m.add_int(0)
# save a copy for later (needed to compute a hash)
self.local_kex_init = m.asbytes()
self._send_message(m)
SSH 协议允许双方对传入和传出方向实施不同的算法集。或者实际上,它允许一方仅针对其中一个方向实施特定算法。
Paramiko 实现了双向的所有算法,因此它使用相同的集合填充传入和传出算法的列表。
参见_parse_kex_init
方法中的代码,它解析由您引用的代码填充的数据包:
client_encrypt_algo_list = m.get_list()
server_encrypt_algo_list = m.get_list()
...
agreed_local_ciphers = list(
filter(
client_encrypt_algo_list.__contains__,
self._preferred_ciphers,
)
)
agreed_remote_ciphers = list(
filter(
server_encrypt_algo_list.__contains__,
self._preferred_ciphers,
)
)