ssh 公钥/私钥对

信息安全 加密 密码学 验证 SSH
2021-09-06 16:15:01

我在理解 ssh 的真正工作原理时遇到问题。我知道它使用公钥密码术来加密消息。但是,我可以 ssh 到服务器,而无需先为我生成公钥/私钥对。我检查了我的 .ssh 文件夹,那里没有 .pub 文件,所以我假设我没有服务器知道的公钥。那么,如果我一开始就没有公钥,服务器如何向我发送加密消息呢?

2个回答

正如@klaustopher 所描述的,SSH 隧道使用 Diffie-Hellman 密钥交换,在客户端和服务器之间建立共享密钥;此共享密钥与对称密码术一起使用,以加密和检查所有随后交换的数据的完整性。

就其本身而言,DH+对称加密很好,但它只完成了一半的工作。DH 协议执行后,客户端和服务器都知道他们现在与……某人建立了安全隧道。但他们不知道是他们只知道在连接的整个生命周期中这将是同一个实体。因此,这很容易受到冒充客户端、服务器或两者兼而有之的主动攻击者的攻击。著名的中间人攻击是双重模拟的案例(攻击者在与客户端对话时充当假服务器,在与服务器对话时充当假客户端)。

为了使传输机密数据和敏感命令的隧道完全安全,客户端和服务器必须相互验证。在协议的第一步中,服务器对他发送的内容进行签名(他的一半 Diffie-Hellman 协议);客户端根据已知的服务器公钥(客户端存储的公钥.ssh/known_hosts)验证该签名。一旦签名被验证,客户端就知道它正在与真正的服务器进行 DH 密钥交换,而不是冒充目标服务器的攻击者。这意味着客户端可以通过隧道安全地发送机密数据。特别是,一旦 DH 完成,第一次交换会这样:

  • (服务器)好的,新客户端。我们做了 DH,我签名了,你验证了,你知道我是合法的服务器。你是谁 ?
  • (客户)我是鲍勃。
  • (服务器)证明它!
  • (客户)这是我的密码:bobisthemasteroftheuniverse
  • (服务器)好的,我知道一个“Bob”用户,这是正确的密码。欢迎,鲍勃。

由于客户端对服务器的身份验证(通过签名验证算法),客户端知道它可以安全地在隧道中发送他的密码。

SSH 协议支持基于签名的客户端身份验证。服务器的 DH 和签名仍然像以前一样完成。但是协议是这样的:

  • (服务器)好的,新客户端。我们做了 DH,我签名了,你验证了,你知道我是合法的服务器。你是谁 ?
  • (客户)我是鲍勃。我有一对钥匙!公钥 ID 为:(...)
  • (服务器)是的,让我们看看。这是一堆随机数据,我挑战你签名:(...)
  • (客户)这是您挑战时新生成的签名:(...)
  • (服务器)很好。我知道一个“鲍勃”,他.ssh/authorized_keys包含一个与您发送的 id 匹配的公钥,并且您在我的挑战中的签名针对该公钥进行了正确验证。欢迎,鲍勃。

HTTPS 或多或少会发生同样的事情。有许多本地差异,例如 HTTPS 客户端通过验证证书而不是从以前的访问中记住它来识别服务器公钥;密码事物可以采取实际网页的形式;但交换的要点是相同的:客户端通过验证其公钥确保它与正确的服务器对话,然后服务器确保它与正确的客户端对话(如果服务器真的有兴趣知道是客户端)通过在隧道运行某种身份验证协议。

这实际上是两种不同的东西。您正在谈论的公钥/私钥对用于身份验证

当您连接到 ssh 服务器时,您的客户端和服务器会协商它们用于加密通信的密钥。从Diffie-Hellmann 密钥交换算法派生的一些算法当您使用浏览器通过 https 协议访问页面时,使用相同的方法。

如果您对 ssh 协议的内部工作原理感兴趣,可以在这里查看它是开放的;)

编辑:但我同意丹尼斯,加密论坛是更好的地方。