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

相关推荐
久曲健的测试窝5 分钟前
Testin云测探索脚本自愈落地路径
运维·人工智能·科技·aigc
奇树谦6 分钟前
本地FastDDS+远端MQTT转发(多主机数据隔离)架构设计与落地
运维·网络
小趴菜一只11 分钟前
SIEM-wazuh安装过程
运维·windows·安全·网络安全
SKH.21 分钟前
Linux驱动-key、中断
linux·运维·服务器
励志师code22 分钟前
数据搬运与存储对接实战:rclone / juicesync 迁移 + 目录对账 + 容器多源挂载
运维·云计算
星恒随风34 分钟前
Linux进程间通信(一):从匿名管道、命名管道到进程池,深入理解Pipe、FIFO与文件描述符
linux·运维·笔记·学习·状态模式
刘胡子大叔1 小时前
服务器不能编译怎么办
运维·服务器
每日品牌解读2 小时前
企业经由 API 调用大模型,推荐哪些拥有数据隐私保护能力的平台?
运维·网络
竣达技术2 小时前
就地显示 + 远程上传,铅酸蓄电池在线监测完整解决方案
运维·数据库
Allstar_432 小时前
拆解全星APQP系统的六大核心质量工具如何联动——汽车供应链企业专业级研发项目管理系统
运维·服务器