我正在阅读一本来自知名出版商的 Linux 管理书籍:
当客户端启动 SSH 握手时,服务器会询问客户端的公钥并根据其允许的公钥对其进行验证。如果匹配,则 SSH 握手成功,服务器与客户端共享其公钥,并建立 SSH 会话。 进一步的客户端-服务器通信遵循标准的加密/解密工作流程。客户端用自己的私钥加密数据,而服务器用客户端的公钥解密数据。响应客户端时,服务器用自己的私钥加密数据,客户端用服务器的公钥解密数据。
这是完全错误的,还是我遗漏了什么?我声明会话通信是通过非对称加密实现的,使用两个密钥对,一个指向客户端->服务器,另一个指向服务器->客户端。
所有其他 Internet 引用状态,服务器和客户端建立一个对称会话密钥,然后在会话期间使用对称加密......
这本书几乎在引用的每一件事上都是错误的。
(如果客户端使用密码身份验证并且没有自己的密钥对,所描述的过程将如何工作?)
这本书可能受到(现在完全过时的)SSHv1 协议的影响,在该协议中,服务器确实使用其非对称 RSA 密钥对来加密/解密某些内容(在SSHv1 中它始终是 RSA),但即便如此,它也仅用于身份验证和不适用于批量数据加密(仍然使用对称算法,例如 3DES)。
但这在 SSHv2 中不再完成,它(就像 TLS 一样)已经完全转向基于 DH 的密钥和基于签名的身份验证。
因此是倒退的和不完整的。由于各种原因,服务器身份验证发生在客户端身份验证之前,但其中一个事实是客户端不一定使用密钥对进行身份验证——例如,它们可能使用普通密码,因此您可能希望在向服务器发送密码之前对其进行身份验证。
此外,这些密钥都根本不用于加密。两个密钥都只用于签名;在本书忽略提及的“密钥交换”过程中(通常是 DH/ECDH 的一种形式),每个会话都会生成新的实际加密密钥。
DH“密钥交换”是首先发生的事情并生成对称密钥(服务器在此阶段提供其公钥),然后建立对称加密,然后客户端向服务器验证自己 - 可能使用密钥对,但可能不会。
这是错误的。尽管 SSH 确实在两个方向(客户端到服务器和服务器到客户端)都使用不同的密钥,但它们仍然与 AES 等对称密码一起使用,因此其中不涉及“公钥”——客户端使用与服务器用于解密相同的对称密钥来加密数据。
实际上,所有协议都只使用对称加密来进行批量数据传输,SSH 和 TLS 都是以这种方式工作的。
您可以查看
ssh -v
或plink -v somehost
查看正在协商的密码;它会向您显示双向使用的 AES 或其他类似的对称密码,并且此类密码没有公钥。