当前位置: 首页 > ai >正文

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

http://www.xdnf.cn/news/4334.html

相关文章:

  • 体育培训的实验室管理痛点 质检LIMS如何重构体育检测价值链
  • TikTok 矩阵运营新手实操保姆级教程 2.0 版本
  • 从一次被抄袭经历谈起:iOS App 安全保护实战
  • 【AWS+Wordpress-准备阶段】AWS注册+创建EC2实例
  • Scrapy框架之Scrapyd部署及Gerapy分布式爬虫管理框架的使用
  • 记录学习《手动学习深度学习》这本书的笔记(十)
  • 协方差与皮尔逊相关系数:从定义到应用的全面解析
  • isNotBlank和isNotEmpty有什么区别?
  • Python学习笔记--FastAPI入门常规操作
  • penEuler操作系统结合豆包测试github仓库8086-Emulator项目
  • react中的用法——setDisabled dva dispatch effects
  • leetcode 160. 相交链表
  • os梳理5——第五章:存储器管理
  • 汽车免拆诊断案例|车辆行驶中急加速车身抖动故障排除 2 例
  • C# NX二次开发:投影曲线和偏置曲线UFUN函数详解
  • Redis--哈希类型
  • 深度学习中的autograd与jacobian
  • C++ 日志系统实战第四步:设计与代码实现详解
  • 从0开始学习大模型--Day03--Agent规划与记忆
  • “胖都来”商标申请可以通过注册不!
  • 如何应对客户在验收后提出新需求?
  • ESP32蓝牙开发笔记(十四)
  • Zsh + iTerm2搭配使用教学,非常舒服,macOS
  • 系统架构-云原生架构设计
  • 14前端项目----登录/注册
  • 【强化学习】#4 蒙特卡洛方法
  • leetcode 70.爬楼梯(c++详细最全解法+补充知识)
  • C++ 备忘录模式详解
  • NVM完全指南:安装、配置与最佳实践
  • 尤雨溪宣布:Vue 生态正式引入 AI