SSH秘钥校验流程

SSH: 即Secure Shell


一、密钥生成(初始化阶段)

  1. 生成密钥对
    用户在客户端(本地设备)通过 ssh-keygen 命令生成 公钥(Public Key)私钥(Private Key),两者是一一对应的非对称加密密钥对。

    • 公钥:用于加密数据或验证签名,可公开分享(无安全风险)。
    • 私钥:用于解密数据或生成签名,需严格保密(泄露会导致身份伪造)。
    • 常见算法:RSA(≥2048 位)、ED25519、ECDSA 等。
  2. 上传公钥到服务器
    用户将公钥内容(如 id_rsa.pub)添加到服务器的 ~/.ssh/authorized_keys 文件中(或 GitHub 等平台的账户设置中)。

    • 服务器存储所有授权用户的公钥,用于后续认证。

二、SSH 密钥校验的核心流程(以 GitHub 为例)

当客户端(如本地 Git)通过 SSH 连接服务器(如 GitHub)时,认证过程如下:

1. 客户端发起连接请求

  • 客户端向服务器发起 TCP 连接,协商 SSH 协议版本和加密算法。
  • 客户端声明支持 密钥认证 方式。

2. 服务器验证客户端身份(核心步骤)

  • 步骤 1:服务器发送随机挑战(Challenge)
    服务器生成一个随机字符串(挑战数据,challenge,并发送给客户端。

    • 关键点:挑战由服务器生成,确保唯一性和防重放攻击。
  • 步骤 2:客户端签名挑战
    客户端使用本地私钥对 challenge 生成签名(实际是对 challenge 的哈希值加密),并将以下信息发送给服务器:

    1. 客户端公钥(或公钥指纹);
    2. 签名结果 signature
  • 步骤 3:服务器验证签名

    1. 服务器根据客户端公钥指纹,在 authorized_keys 中查找匹配的公钥;
    2. 用公钥解密签名,得到哈希值 H1
    3. 服务器本地计算 challenge 的哈希值 H2
    4. 对比 H1H2
      • 一致 → 认证通过(客户端拥有私钥);
      • 不一致 → 认证失败。

3. 完成认证,建立加密通道

  • 认证通过后,双方协商生成会话密钥(Session Key),后续所有通信通过对称加密传输(如 AES),确保效率和安全性。

三、关键技术点解析

1. 非对称加密与签名机制

  • 签名(Signing)
    客户端对 challenge 的哈希值用私钥加密生成签名(非对称加密的逆向操作)。
    • 私钥的保密性确保只有合法用户能生成有效签名。
  • 验证(Verification)
    服务器用公钥解密签名,得到哈希值。若与 challenge 的哈希一致,则证明签名有效。

2. known_hosts 文件的作用

  • 防御中间人攻击(MITM)
    首次连接时,服务器会发送自己的主机公钥(非用户公钥),客户端需验证其指纹是否与官方公布的一致。
    • 若验证通过,主机公钥指纹存入 ~/.ssh/known_hosts;后续连接时自动比对,防止攻击者冒充服务器。

四、疑问解答

1. 服务器认证客户端时,基本流程

  • 第一次交互:客户端发起连接请求,声明支持密钥认证方式。
  • 第二次交互:服务器生成随机挑战(challenge),并发送给客户端(而非客户端自己生成)。
  • 第三次交互:客户端用私钥对 challenge 签名,将签名返回服务器。
  • 服务器验证签名:用存储的公钥解密签名,若还原的 challenge 一致,则认证通过。

结论:实际是两次消息交互(服务器发送挑战,客户端返回签名),但整体流程包含多次通信(TCP 握手、协议协商等)。


2. 非对称加密与身份验证原理

  • 非对称加密:公钥加密的数据只能用私钥解密,私钥签名的数据可用公钥验证。
  • 验证身份的流程
    1. 服务器发送一个随机挑战(challenge)。
    2. 客户端用私钥对 challenge 签名(本质是加密哈希值)。
    3. 服务器用公钥解密签名,得到哈希值,与本地计算的 challenge 哈希值比对。
    4. 若一致,证明客户端拥有私钥(因为只有私钥能生成有效签名)。

关键点:私钥的保密性保证了只有合法用户能生成有效签名,公钥的公开性允许任何人验证签名。


3. 签名解密后的结果是否唯一?

  • 是唯一的,但需满足以下条件:
    • 签名算法是确定性的(如 RSA 使用 PKCS#1 v1.5)或包含抗碰撞哈希(如 SHA-256)。
    • 挑战(challenge)是唯一的(服务器随机生成,避免重放攻击)。
  • 原理:签名本质是对挑战的哈希值用私钥加密。公钥解密签名后得到哈希值,若与服务器本地计算的哈希一致,则验证通过。

4. 为什么公钥泄露无风险?

  • 公钥的特性
    • 公钥是公开设计的,无法逆向推导出私钥(基于数学难题,如大数分解、椭圆曲线离散对数)。
    • 公钥仅用于加密或验证签名,无法用于生成签名或解密数据。
  • 攻击者仅有公钥时
    • 无法冒充客户端(无私钥无法生成有效签名)。
    • 无法解密已加密的数据(若用公钥加密,需私钥解密)。
  • 风险仅存在于私钥泄露:私钥是身份的唯一凭证,必须严格保密。

5.公钥泄露后,劫持者能否破解传输的信息?

结论:即使公钥泄露,劫持者也无法直接解密 SSH 通信中的数据。

  • SSH 传输阶段使用对称加密
    SSH 认证通过后,客户端和服务器会协商一个 对称加密密钥(Session Key),后续所有数据传输均通过对称加密(如 AES)进行。
    • 对称加密的密钥是临时生成的,且通过安全通道(如 Diffie-Hellman 密钥交换协议)协商,与公钥无直接关联。
    • 公钥仅用于身份认证阶段,不参与数据加密。
  • 公钥的作用限制
    • 公钥的泄露仅意味着攻击者可以知道用户的公钥,但无法:
      1. 推导出私钥(基于非对称加密算法的数学难题);
      2. 解密已加密的 SSH 通信数据(因为数据由对称密钥加密)。
  • 客户端被劫持的特殊情况
    • 若客户端被完全劫持(如恶意软件控制),攻击者可直接获取客户端的私钥和会话密钥,此时所有通信将暴露。
    • 但这与公钥泄露无关,而是私钥或会话密钥泄露的问题。

6.加密与签名的区别

加密(Encryption)

  • 目的:确保数据 机密性(防止内容被窃听)。
  • 流程
    1. 发送方用 接收方的公钥 加密数据 → 生成密文;
    2. 接收方用 自己的私钥 解密 → 还原原始数据。
  • 典型场景:A 向 B 发送加密消息,只有 B 能解密(因为 B 持有私钥)。

签名(Signing)

  • 目的:确保数据 完整性身份认证(验证发送者身份)。
  • 流程
    1. 发送方对数据生成哈希值 → 用 自己的私钥 加密哈希值 → 生成签名;
    2. 接收方用 发送方的公钥 解密签名 → 得到哈希值 H1
    3. 接收方本地计算数据的哈希值 H2 → 对比 H1H2
  • 典型场景:A 向 B 发送签名消息,B 验证签名是否由 A 的私钥生成。

关键区别

特性 加密 签名
操作方向 公钥加密,私钥解密 私钥签名,公钥验证
核心目标 保密性 身份认证 + 完整性
密钥使用 他人公钥加密,自己私钥解密 自己私钥签名,他人公钥验证

SSH秘钥校验流程
https://aimo6.github.io/2025/04/29/SSH秘钥校验流程/
作者
lsx
发布于
2025年4月29日
许可协议