我正在编写一个程序,尝试建立与服务器的 SSH 连接(开启严格密钥检查)。文档说,如果没有严格的密钥检查,我就会容易受到中间人攻击。
我了解主机密钥验证会检查我们尝试连接的服务器是否具有/etc/ssh
与我们~/.ssh/known_hosts
文件中相同的合理主机密钥(存储在中)。
我对主机密钥验证的理解正确吗?
但是,由于主机密钥是公开的(ssh-keyscan <hostname>
),任何人都可以通过复制和使用该主机密钥来欺骗服务器吗?
答案1
由于主机密钥是公开的,任何人都可以通过复制和使用该主机密钥来欺骗服务器吗?
不。民众服务器的密钥是公开的。要欺骗服务器,需要它的私人的关键。它们是不同的,它们在数学上是相连的,它们形成了一个一对。其背后的数学原理使得从公钥推导出私钥变得非常非常困难(计算成本高昂)。
知道服务器的公钥(在本地~/.ssh/known_hosts
),您的 SSH 客户端可以构建一个“谜题”供服务器解决。当且仅当服务器知道相应的私钥时,解决这个谜题才容易。因此,如果服务器解决了这个谜题,那么您的客户端就知道服务器拥有正确的私钥,因此它是真正的服务器。
反过来:当您想要使用私钥进行身份验证时,服务器(拥有您~/.ssh/authorized_keys
想要登录的用户的公钥)会为您的 SSH 客户端构建一个“谜题”以供解决。当且仅当客户端知道相应的私钥(即您的私钥)时,解决这个谜题才容易。您的客户端确实知道它,它解决了这个谜题,服务器知道这是您。
潜在的欺骗者可以知道服务器的公钥。这样他们就可以检查真正的服务器是否真实(通过构建谜题),但他们仍然无法冒充服务器,因为他们无法轻松解决其他人(例如您的)为验证服务器真实性而设计的谜题。他们需要服务器的私钥才能做到这一点。
类似地,如果有人知道您的公钥但不知道您的私钥,他们就无法向您可以验证身份的服务器(使用您的私钥)进行验证。
私钥应该保密。
此外,客户端和服务器使用会话密钥加密通信。他们首先各自挑选一些(随机)秘密和一些可从秘密中轻松得出的信息。他们交换所得到的信息,并都得出相同的秘密会话密钥。该过程背后的数学原理使得从交换的信息中得出会话密钥(或起始秘密)变得非常非常困难(计算成本高昂)。外部观察者无法预测会话密钥。但起始秘密和从另一端收到的信息足以在两端获得相同的密钥。密钥取决于两个起始秘密,因此任何一端都无法强制使用某个特定密钥。
这发生在身份验证之前。事实上,身份验证过程使用会话密钥来构建“谜题”。由于这个原因,中间人(在客户端前面扮演服务器,在服务器前面扮演客户端)不能简单地传递谜题及其解决方案。他与客户端的通信将使用与服务器通信不同的会话密钥。他可以通过用一个密钥解密并用另一个密钥加密来传递数据。但如果他传递一个谜题,则谜题中内置的会话密钥将与另一端期望的不匹配。身份验证将失败。中间人需要实际解决谜题才能传递它们(或者更确切地说,将它们从一个会话密钥“翻译”到另一个会话密钥)。或者他需要构建独立的谜题。无论如何,他都需要知道私钥才能成功地坐在中间并窃听、修改或注入数据。
总结一下:如果不知道服务器的私钥,攻击者就无法自行冒充服务器,也无法从真正的服务器中继身份验证。