SSHv2 密钥交换(Key Exchange)详解

1. 算法协商

在密钥交换开始前,客户端和服务端会协商确定本次会话使用的算法组合。具体过程如下:

  1. 交换算法列表

    • 客户端和服务端各自发送支持的算法列表,包括:
      • 密钥交换算法 (如 diffie-hellman-group14-sha256
      • 加密算法 (如 aes256-ctr
      • MAC算法 (如 hmac-sha2-256
      • 压缩算法 (如 none 表示不压缩)
  2. 选择共同支持的算法

    • 双方从对方的列表中按优先级选择第一个匹配的算法。
    • 例如:
      • 客户端发送的密钥交换算法列表:curve25519-sha256, diffie-hellman-group14-sha256
      • 服务端支持的列表:diffie-hellman-group14-sha256, ecdh-sha2-nistp256
      • 最终选定 diffie-hellman-group14-sha256

2. 密钥交换流程

Diffie-Hellman Group 14 (2048-bit) 为例,说明临时密钥的生成与会话密钥的计算。

步骤 1:生成临时密钥对
  • 客户端服务端 各自独立生成一对 临时 公私钥:
    • 私钥:随机大整数 ( x )(客户端私钥为 ( x_C ),服务端私钥为 ( x_S )),保密存储。
    • 公钥:通过公式 ( g^{x} \mod p ) 计算得到(( g ) 和 ( p ) 是公开的 Group14 参数)。
步骤 2:交换公钥
  • 客户端将临时公钥 ( g^{x_C} \mod p ) 发送给服务端。
  • 服务端将临时公钥 ( g^{x_S} \mod p ) 发送给客户端。
步骤 3:计算共享密钥(Shared Secret)
  • 客户端 使用服务端的公钥计算共享密钥:

    K = (g^{x_S})^{x_C} \\mod p = g\^{x_S x_C} \\mod p

  • 服务端 使用客户端的公钥计算共享密钥:

    K = (g^{x_C})^{x_S} \\mod p = g\^{x_C x_S} \\mod p

  • 根据模幂运算性质,双方最终得到相同的共享密钥 ( K )。
步骤 4:派生会话密钥

共享密钥 ( K ) 不会直接用于加密数据 ,而是作为输入,结合其他参数通过哈希函数生成最终会话密钥。

具体流程:

  1. 收集交换参数
    • 客户端和服务端的临时公钥(( g^{x_C}, g^{x_S} ))
    • 共享密钥 ( K )
    • 双方初始交换的随机数(Client/Server Hello 中的 nonce)
  2. 哈希计算
    使用协商的哈希算法(如 SHA-256)处理所有参数:

    \\text{会话密钥} = \\text{SHA-256}(K \|\| g\^{x_C} \|\| g\^{x_S} \|\| \\text{ClientNonce} \|\| \\text{ServerNonce})

  3. 分割密钥材料
    哈希结果被分割为多个密钥,用于不同用途:
    • 客户端到服务端的加密密钥
    • 服务端到客户端的加密密钥
    • 客户端到服务端的 MAC 密钥
    • 服务端到客户端的 MAC 密钥

3. 服务端公钥 vs 临时公钥
  • 服务端长期公钥(主机密钥)

    • 用途:验证服务端身份(防止中间人攻击)。
    • 存储位置:服务端的 /etc/ssh/ssh_host_rsa_key(默认路径)。
    • 客户端首次连接时需手动确认其指纹,之后存储在 ~/.ssh/known_hosts
  • 临时公钥

    • 用途:仅用于本次会话的密钥交换(Diffie-Hellman)。
    • 生命周期:会话结束后立即销毁,确保前向保密(即使长期密钥泄露,历史会话仍安全)。

4. 完整流程示例

假设客户端(C)和服务端(S)使用 Diffie-Hellman Group14

  1. 参数定义

    • 公共素数 ( p = 2^{2048} - 2^{1984} - 1 + 2^{64} \times \lfloor 2^{1918} \pi \rfloor + 124476 )
    • 生成器 ( g = 2 )
  2. 密钥生成

    • C 随机选择私钥 ( x_C = 12345 ),计算公钥 ( g^{x_C} \mod p = A )
    • S 随机选择私钥 ( x_S = 67890 ),计算公钥 ( g^{x_S} \mod p = B )
  3. 交换公钥

    • C → S 发送 ( A )
    • S → C 发送 ( B )
  4. 计算共享密钥

    • C 计算 ( K = B^{x_C} \mod p = (g{x_S}){x_C} \mod p = g^{x_S x_C} \mod p )
    • S 计算 ( K = A^{x_S} \mod p = (g{x_C}){x_S} \mod p = g^{x_C x_S} \mod p )
    • 结果相同:( K = g^{x_C x_S} \mod p )
  5. 派生会话密钥

    • 输入 ( K )、( A )、( B )、ClientNonce、ServerNonce 到 SHA-256
    • 输出 256 位哈希值,分割为多个密钥。

5. 安全性保障
  • 前向保密(Perfect Forward Secrecy, PFS)
    每次会话使用临时密钥,即使攻击者获取服务端长期私钥,也无法解密历史会话。
  • 抗中间人攻击
    客户端通过验证服务端长期公钥指纹确认身份。
  • 算法强度
    2048-bit 的 Group14 提供足够安全性(截至 2023 年未被攻破)。

总结

SSHv2 的密钥交换通过 临时密钥对Diffie-Hellman 算法 确保会话密钥的安全生成,同时通过 哈希函数派生前向保密设计 抵御多种攻击。服务端长期公钥用于身份验证,而临时公钥仅服务于本次会话,两者分工明确,共同保障协议的安全性。

相关推荐
Fcy64844 分钟前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满1 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器
代码游侠1 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Harvey9031 小时前
通过 Helm 部署 Nginx 应用的完整标准化步骤
linux·运维·nginx·k8s
珠海西格电力科技2 小时前
微电网能量平衡理论的实现条件在不同场景下有哪些差异?
运维·服务器·网络·人工智能·云计算·智慧城市
释怀不想释怀3 小时前
Linux环境变量
linux·运维·服务器
zzzsde3 小时前
【Linux】进程(4):进程优先级&&调度队列
linux·运维·服务器
聆风吟º4 小时前
CANN开源项目实战指南:使用oam-tools构建自动化故障诊断与运维可观测性体系
运维·开源·自动化·cann
NPE~5 小时前
自动化工具Drissonpage 保姆级教程(含xpath语法)
运维·后端·爬虫·自动化·网络爬虫·xpath·浏览器自动化
神梦流5 小时前
GE 引擎的内存优化终局:静态生命周期分析指导下的内存分配与复用策略
linux·运维·服务器