【问题标题】:How does SSH public key authentication work (picking up right keys)SSH 公钥认证是如何工作的(选择正确的密钥)
【发布时间】:2014-06-28 02:50:51
【问题描述】:
据我所知,关于 SSH 身份验证以及根据 Alice 和 Bob 的许多解释,有一些主要步骤:
- 客户端生成一对公钥/私钥并将公钥发布到服务器。
- 当服务器收到一个公钥认证请求时,它会生成一个随机数据,用客户端的公钥对其进行加密,然后发送给客户端。
- 客户端使用私钥解密此数据并将其作为真实性证明发回。
我希望你们中的一些人帮助我了解当我通过 SSH 协议克隆任意存储库时,GitHub 服务器如何知道在第 2 步中选择哪个公钥?
它有数百万个用户公钥可供选择。并且用户可能已经在他的机器上安装了许多私钥。
【问题讨论】:
标签:
authentication
github
ssh
cryptography
【解决方案1】:
协议比您想象的要复杂一些。手册页描述了客户端告诉服务器它想要使用哪个密钥:
文件~/.ssh/authorized_keys 列出了允许登录的公钥。当
用户登录,ssh 程序告诉服务器它想使用哪个密钥对
验证。客户端证明它可以访问私钥并且服务器检查
相应的公钥被授权接受该帐户。
relevant SSH rfc 详细说明客户端实际上通过 SSH_MSG_USERAUTH_REQUEST 请求发送了整个公钥。
在大多数情况下,使用公钥 github 应该能够查看相应的用户。不过,我不知道当两个帐户共享一个密钥时会发生什么。
【解决方案2】:
要了解 SSH 身份验证的工作原理,可能需要阅读与 SSH 2.0 相关的所有五个 RFC:RFC4250、RFC4251、RFC4252、RFC4253 和 RFC4254。
有四个信息有助于确保 SSH 身份验证正常工作:会话 ID、服务器公钥、客户端公钥和服务器上的用户名。
在建立 TCP 连接之后和客户端通过身份验证之前,在密钥交换 (KEX) 期间创建会话 ID。会话 ID 保存在客户端和服务器上。当客户端通过发送SSH_MSG_USERAUTH_REQUEST 消息对服务器进行身份验证时,它会提供服务器上的用户名、客户端公钥以及使用客户端公钥解密时包含会话 ID 的签名。将用户名与会话 ID 匹配就足够了,然后建立一个安全会话,然后建立一个用于执行远程 git 命令的安全通道。
服务器公钥在密钥交换期间提供给客户端。它存储在 ~/.ssh/known_hosts 文件中。当服务器签名发生变化时,SSH 客户端将显示服务器凭据更改的警告并停止身份验证过程。
您可以参考this article,了解有关无密码 SSH 名字对象下的公钥身份验证的更多详细信息(公钥不提供密码和密码)。