GM/T 0129-2023 SSH 密码协议规范深度解析:密码算法与握手流程的原理、实施与安全分析

协议详解 · 2026-07-09

概述

GM/T 0129-2023《SSH 密码协议规范》是由国家密码管理局于 2023 年 12 月发布、2024 年 6 月 1 日正式实施的密码行业标准。该规范基于 IETF RFC 4253(SSH 传输层协议)框架,规定了将国密算法(SM2/SM3/SM4/SMS4)集成到 SSH 协议中的技术要求。

截至 2026 年 7 月,GM/T 0129-2023 已实施满两年,是国密改造中服务器远程管理安全的核心标准之一。本文将从协议原理、消息格式、密钥交换流程、实施要点四个维度进行完整分析。

标准背景与体系定位

2.1 为什么需要国密 SSH?

传统 SSH(OpenSSH)使用国际算法:DH-GEX/GROUP14 密钥交换、RSA/ECDSA 身份认证、AES-CTR/CBC 加密。在密评和等保三级以上系统中,国密合规要求替换为:

  • 密钥交换:SM2 椭圆曲线密钥交换(替代 DH)
  • 数字签名:SM2 签名(替代 RSA/ECDSA)
  • 对称加密:SM4(替代 AES)
  • 完整性校验:HMAC-SM3(替代 HMAC-SHA256)
GM/T 0129-2023 将这些替换标准化,定义了国密 SSH 的完整协议框架。

2.2 配套标准体系

GM/T 0129-2023 不是孤立标准,它依赖以下配套标准:

标准定位
GM/T 0003.1-2012SM2 椭圆曲线公钥密码算法(密钥交换协议基础)
GM/T 0003.2-2012SM2 数字签名算法(身份认证基础)
GM/T 0004-2012SM3 密码杂凑算法(KDF、HMAC 基础)
GM/T 0002-2012SM4 分组密码算法(会话加密基础)
GM/T 0009-2023SM2 密码算法使用规范(密钥格式)
RFC 4251-4254SSH 协议架构(协议框架参考)

2.3 标准适用范围

规范适用于:

  • 采用国密算法的 SSH 服务器和客户端
  • 安全认证网关的 SSH 代理模块
  • 运维审计系统的 SSH 代理
不适用于:
  • 采用 ZUC 序列密码的移动通信场景(参考 GM/T 0001)
  • 专用硬件加密机(参考 GM/T 0046)

协议架构

3.1 四层协议结构

GM/T 0129-2023 保留了 SSH 的四层架构,仅替换每层的算法:

CODE
+-----------------------+
|  用户认证协议         |  ← 仍然基于用户名/公钥/密码
|  (SSH-USERAUTH)       |     但公钥使用 SM2 证书
+-----------------------+
|  连接协议             |  ← 多路复用通道
|  (SSH-CONNECT)        |
+-----------------------+
|  传输层协议           |  ← 国密算法替换的核心层
|  (SSH-TRANS)          |     密钥交换、服务器认证、加密/完整性
+-----------------------+
|  TCP/IP 传输层        |  ← 不变
+-----------------------+

3.2 算法套件(Algorithm Packages)

规范定义了一套完整的国密算法套件:

密钥交换算法(三种模式):

算法名称说明前向保密
sm2-exchSM2 密钥交换(基于 GM/T 0003.3)
sm2-exch-sm3SM2 密钥交换 + SM3 KDF
ecdh-sha2-sm2p256r1ECDH over SM2 曲线(兼容模式)
服务器认证算法

算法名称说明
sm2-sign-sm3SM2 数字签名(使用 SM3 哈希)
对称加密算法

算法名称说明
sm4-ctrSM4 CTR 模式(推荐)
sm4-cbcSM4 CBC 模式(兼容旧系统)
MAC 算法

算法名称说明
hmac-sm3HMAC-SM3(256-bit 标签)
公钥格式

格式名称说明
sm2-pubkey-04SM2 公钥非压缩格式(0x04xy)
sm2-certv3-sm3SM2 证书 + SM3 签名

握手流程详解

4.1 整体握手时序

4.2 消息格式

SSH_MSG_KEXINIT(算法协商):

CODE
byte    SSH_MSG_KEXINIT (value = 20)
byte[16] 随机 cookie (16 字节随机数)
name-list kex_algorithms        ; 支持的密钥交换算法列表
name-list server_host_key_algorithms ; 服务器主机密钥算法
name-list encryption_algorithms_c2s  ; 客户端到服务器加密
name-list encryption_algorithms_s2c  ; 服务器到客户端加密
name-list mac_algorithms_c2s         ; C2S MAC 算法
name-list mac_algorithms_s2c         ; S2C MAC 算法
name-list compression_algorithms     ; 压缩算法
boolean first_kex_packet_follows     ; 是否有猜测包
uint32  0 (reserved for extension negotiation)

KEXINIT 中国密算法的 name-list 示例

4.3 SM2 密钥交换(KEX)

步骤 1:客户端发送 KEX_INIT

CODE
byte    SSH_MSG_KEX_SM2_INIT (value = 30)
string  SM2_POINT(R_client)   ; 客户端临时公钥(91 字节)
string  random_client         ; 客户端随机数(32 字节)

SM2_POINT 的编码格式:

CODE
0x04 || x_coord (32 bytes) || y_coord (32 bytes) = 65 字节
+ length prefix (4 bytes) = 69 字节

实际可能是带有 OID 前缀的完整格式(91 字节)。

步骤 2:服务器发送 KEX_REPLY

CODE
byte    SSH_MSG_KEX_SM2_REPLY (value = 31)
string  server_public_key    ; 服务器 SM2 公钥(包含 OID)
string  SM2_POINT(R_server)  ; 服务器临时公钥
string  server_signature     ; 服务器签名(SM2-SM3)

步骤 3:签名构造(服务器对握手消息签名)

签名内容 $Z$ 的计算:

CODE
Z = session_id || SSH_MSG_KEXINIT || client_kexinit_payload
    || server_kexinit_payload || server_host_key_blob
    || R_client_payload || R_server_payload
    || shared_secret_hex

其中 session_id 是首次密钥交换的计算结果(后续交换复用),用于绑定会话。

步骤 4:共享密钥计算

$$dS = \text{SM2KeyExchange}(d_{\text{server}}, R_{\text{client}}, d_{\text{client}}, R_{\text{server}})$$

GM/T 0129-2023 采用双方贡献式交换:

CODE
客户端: S = [h * (d_client + x_client_bar * r_client)] * (R_server + [x_server_bar] * P_server)
服务器: S = [h * (d_server + x_server_bar * r_server)] * (R_client + [x_client_bar] * P_client)

双方通过 SM2 密钥交换协议(GM/T 0003.3)计算得到相同的共享点 $S = (S_x, S_y)$。

步骤 5:KDF 密钥派生

从共享点 $S$ 派生会话密钥:

CODE
K = KDF(S_x || S_y || session_id, key_length)

派生出的密钥按顺序分为:

  • encryption_key_client_to_server(IV + encryption key)
  • encryption_key_server_to_client(IV + encryption key)
  • integrity_key_client_to_server(MAC 密钥)
  • integrity_key_server_to_client(MAC 密钥)

4.4 用户认证

握手完成后,通过 SSH-USERAUTH 协议进行身份认证。GM/T 0129 定义了两种国密认证方式:

publickey 认证

CODE
byte    SSH_MSG_USERAUTH_REQUEST (value = 50)
string  user name (ISO-10646 UTF-8)
string  service name = "ssh-connection"
string  "publickey"
boolean TRUE (表示包含签名)
string  public key algorithm name = "sm2-sign-sm3"
string  public key blob (服务器公钥格式)
string  signature (SM2-SM3 签名)

服务器验证签名的输入 = session_id || SSH_MSG_USERAUTH_REQUEST || ...

password 认证(使用 SM4 加密密码):

握手后密码在 SM4 加密通道中传输,本身无需额外国密算法。

实施建议

5.1 软件选型

截至 2026 年 7 月,国密 SSH 的实现主要有:

方案说明成熟度
Tongsuo + OpenSSH 补丁阿里巴巴 Tongsuo(国密 OpenSSL)+ OpenSSH 8.x★★★☆☆
libssh2 国密版libssh2 社区 + GMSSL 绑定★★☆☆☆
商业堡垒机(齐治、绿盟等)内置国密 SSH 服务端★★★★☆
自研 GMSSH基于 GMSSL 从零开发★☆☆☆☆
建议
  • 新建系统优先选择 Tongsuo 方案(开源、活跃维护、标准化程度高)
  • 已有系统可通过堡垒机代理实现国密 SSH,避免改造

5.2 配置参考(Tongsuo + OpenSSH)

BASH
# 使用国密算法
KexAlgorithms sm2-exch-sm3,sm2-exch,curve25519-sha256
HostKeyAlgorithms sm2-sign-sm3,rsa-sha2-512
Ciphers sm4-ctr,aes256-ctr
MACs hmac-sm3,hmac-sha2-256

# 国密 SM2 主机密钥
HostKey /etc/ssh/ssh_host_sm2_key
HostCertificate /etc/ssh/ssh_host_sm2_key-cert.pub

# 启用混合模式(同时支持国密和国际算法)
# 客户端如果没有国密支持,会 fallback 到 curve25519 + rsa-sha2-512
BASH
# 生成 SM2 主机密钥
ssh-keygen -t sm2 -f /etc/ssh/ssh_host_sm2_key -C "SM2 host key $(date +%Y%m%d)"

# 证书签名(使用 CA 的 SM2 密钥)
ssh-keygen -s /etc/ssh/ca_sm2_key \
    -I host.example.com \
    -h \
    -V +520w \
    /etc/ssh/ssh_host_sm2_key.pub

5.3 客户端连接

5.4 互操作性注意事项

问题:标准 OpenSSH 不支持规范定义的 sm2-exch-sm3

这是因为 GM/T 0129-2023 发布晚于 OpenSSH 主流版本。标准 OpenSSH 9.x 不理解国密算法。

解决方案

  • 使用 Tongsuo fork 的 OpenSSH(aliopcode/openssh-gm)
  • 通过安全网关代理(国密 OpenSSH ↔ 国密代理 ↔ 代理 ⇄ 客户端)
  • 等待 OpenSSH 社区支持(IETF draft 暂无 SM2 SSH 规范)
混合部署建议
  • 运维堡垒机:完整国密 SSH(SM2 证书 + SM4-ctr + HMAC-SM3)
  • 普通服务器:国际算法旧 SSH(过渡期)
  • 客户端:配置两组算法,自动选择

安全性分析

6.1 密钥交换安全

攻击类型SSH-RSA/DHSSH-SM2分析
被动窃听安全(DH 提供机密性)安全(SM2 KE 提供机密性)等价
中间人攻击依赖主机密钥指纹依赖 SM2 证书SM2 需经 CA 签发
前向保密DH/ECDH 提供sm2-exch 提供等价
量子攻击脆弱脆弱(同属 ECC)需迁移到 ML-KEM

6.2 SM2 vs ECDSA vs Ed25519(服务器认证)

对比项SM2 (GM/T 0003.2)ECDSA (NIST P-256)Ed25519
签名输出R+S (64 字节) 或 DER (70-72 字节)DER (70-72 字节)64 字节
安全性假设SM2 曲线离散对数NIST P-256 离散对数Curve25519 离散对数
侧信道防护恒定时间实现较少成熟内置
随机数要求高($k$ 泄露=私钥泄露)无(确定性签名)
国密合规
ISO/IEC 标准ISO/IEC-14888-3FIPS-185
注意:SM2 签名对随机数的要求与 ECDSA 相同——若 $k$ 泄露,私钥可被恢复。生产环境中必须使用密码学安全的随机数生成器(CSPRNG)。

6.3 SM4-ctr vs AES-256-ctr

SM4 和 AES 同属 128-bit 分组密码,密钥长度均为 128-bit:

  • SM4 没有已知的差分攻击优于暴力破解(与 AES 类似)
  • SM4 的硬件加速在原生机房中较少(需 SM4-NI 或专用密码卡)
  • 在云环境中,SM4 性能可能落后于 AES-NI 加速的 AES-256
  • 国密环境中 SM4 是必需合规项

6.4 已知限制与风险

限制 1:SM2 密钥格式未国际标准化

OpenSSH 8.x 不理解 ssh-sm2 公钥格式。使用 Tongsuo fork 后才能完整支持。

限制 2:证书链复杂性

SM2 数字证书遵循 GM/T 0015(基于 X.509v3,但扩展字段不同)。国际 CA 不签发 SM2 证书,需要自建 CA 或使用国内 CA(如 CFCA、BJCA、SinPKI)。

限制 3:密钥派生强度

GM/T 0003.3 的 KDF 是 SM3 迭代哈希输出,无 salt 和 info 扩展。与 HKDF 相比缺少域分离(domain separation),在多密钥派生场景下建议嵌入 session_id 作为唯一化源。

限制 4:缺少后量子密钥交换

SM2 密钥交换基于 ECDLP,可被量子计算机破解(Shor 算法)。与后量子方案(如 ML-KEM)的混合密钥交换尚未在国密 SSH 中标准化(参考:NIST FIPS 203 ML-KEM 草案)。

与相关实践的关联

7.1 等保三级密码要求

GM/T 0129-2023 是等保 2.0 三级系统"网络和通信安全"层面的重要合规依据:

  • 数据传输保密性:SM4 加密 ✅
  • 数据传输完整性:HMAC-SM3 ✅
  • 身份鉴别:SM2 签名 ✅
  • 密码算法合规:国密算法 ✅

7.2 密评合规

密评机构在检查 SSH 服务时,会验证:

  • 算法是否为国密(检查 /etc/ssh/sshd_config
  • 证书是否由合规 CA 签发
  • 密钥强度是否满足要求(SM2-256bit / SM4-128bit)
  • 密钥管理是否符合 GM/T 0018(密码设备应用接口)

7.3 典型部署架构

总结

GM/T 0129-2023 将 SSH 协议中国密算法的应用标准化,解决了以下核心问题:

  • 明确定义了 SSH 各层中国密算法的选择和使用方式
  • 规定了 SM2 密钥交换的握手消息格式和签名方式
  • 提供了与国际 SSH 协议的混合兼容方案
但在实际部署中仍需注意:
  • 标准 OpenSSH 暂未原生支持,需使用 Tongsuo fork
  • SM2 证书体系需要国内 CA 支持
  • 前向保密依赖 SM2 的临时密钥生成质量
  • 后量子迁移路径尚不明确
国密 SSH 是密码人必须掌握的核心协议知识。等保三级以上系统的远程管理通道必须在 2027 年前完成国密改造,掌握该标准对每一位网络密码工程师都有直接的实践价值。

参考来源

  • GM/T 0129-2023《SSH 密码协议规范》(国家密码管理局,2023-12 发布,2024-06-01 实施)
  • GM/T 0003.3-2012《SM2 椭圆曲线公钥密码算法 第 3 部分:密钥交换协议》
  • RFC 4253(SSH Transport Layer Protocol)
  • RFC 4252(SSH Authentication Protocol)
  • Tongsuo 项目:
  • GMT 0054-2018《信息系统密码应用基本要求》

*标准文本可通过全国标准信息公共服务平台(std.samr.gov.cn)查询:GM/T 0129-2023*