GM/T 0129-2023 SSH 密码协议实战:基于 Tongsuo 部署国密 OpenSSH 完整指南

国密算法 · 2026-07-28 · 6 阅读

前言

SSH(Secure Shell)是远程服务器管理、文件传输和端口转发的事实标准。等保 2.0 和密评要求远程管理通道必须采用国密算法,但标准 OpenSSH 8.x 只支持国际算法(curve25519、aes256-ctr、hmac-sha2)。

GM/T 0129-2023《SSH 密码协议规范》于 2023-12-04 发布、2024-06-01 实施,定义了 SSH 协议中国密算法套件的协商机制、密钥交换、身份认证和会话加密。本文基于该标准原文,结合阿里巴巴 Tongsuo 项目的 OpenSSH 补丁,给出国密 SSH 的完整部署方案。

标准概述

GM/T 0129-2023 的核心设计目标是在不改变 SSH 协议框架的前提下,将算法替换为国密算法族。它沿用了 RFC 4251-4253 的协议架构(SSH Architecture、Authentication、Transport Layer),仅在算法协商和密钥派生两个环节做了国密适配。

配套标准体系

标准编号名称在 SSH 中的角色
GM/T 0003.3-2012SM2 密钥交换协议密钥协商(前向保密)
GM/T 0003.2-2012SM2 数字签名算法服务器身份认证
GM/T 0004-2012SM3 密码杂凑算法KDF、HMAC
GM/T 0002-2012SM4 分组密码算法会话数据加密
GM/T 0009-2023SM2 密码算法使用规范密钥格式定义

算法套件

GM/T 0129-2023 定义了完整的国密算法套件,覆盖 SSH 协议的四个层次:

层次算法标识说明推荐度
密钥交换sm2-exch-sm3SM2 密钥交换 + SM3 KDF★★★★★
密钥交换sm2-exchSM2 密钥交换(基础版)★★★☆☆
服务器认证sm2-sign-sm3SM2 签名 + SM3 哈希★★★★★
对称加密sm4-ctrSM4 CTR 模式(流式加密,无需填充)★★★★★
对称加密sm4-cbcSM4 CBC 模式(兼容旧实现)★★★☆☆
MAChmac-sm3HMAC-SM3(256-bit 认证标签)★★★★★
注意sm4-ctr 是首选加密模式。CTR 模式将分组密码转换为流密码,天然支持任意长度数据,无需填充,避免了 CBC 模式的填充 Oracle 攻击面。

握手流程

GM/T 0129-2023 的握手在 SSH 协议框架内完成,关键消息如下:

CODE
客户端                                          服务器
  |                                              |
  |---- SSH_MSG_KEXINIT (算法列表) ------------->|
  |<- SSH_MSG_KEXINIT (算法列表) ----------------|
  |                                              |
  |---- SSH_MSG_KEX_SM2_INIT ------------------>|
  |    (R_client || random_client)               |
  |                                              |
  |<- SSH_MSG_KEX_SM2_REPLY --------------------|
  |    (server_pubkey || R_server || signature)  |
  |                                              |
  |==== 会话密钥派生(双方独立计算)====|

关键消息格式

SSH_MSG_KEX_SM2_INIT(byte = 30):

CODE
byte    SSH_MSG_KEX_SM2_INIT
string  SM2_POINT(R_client)   ; 客户端临时公钥(非压缩格式 0x04||x||y)
string  random_client         ; 客户端随机数(32 字节)

SSH_MSG_KEX_SM2_REPLY(byte = 31):

CODE
byte    SSH_MSG_KEX_SM2_REPLY
string  server_public_key     ; 服务器长期 SM2 公钥
string  SM2_POINT(R_server)   ; 服务器临时公钥
string  server_signature      ; SM2-SM3 签名

共享密钥派生

双方从共享点 S = (Sx, Sy) 派生会话密钥:

PYTHON
# 简化示意(实际遵循 GM/T 0003.3-2012 第 6.1 节)
K = KDF(Sx || Sy || session_id, key_length)

派生的密钥材料按顺序分割为 6 段:

序号密钥用途长度
1IV (client → server)16 字节
2Encryption Key (client → server)16 字节
3IV (server → client)16 字节
4Encryption Key (server → client)16 字节
5Integrity Key (client → server)32 字节
6Integrity Key (server → client)32 字节

服务器签名构造

服务器对握手过程进行签名,防止中间人攻击:

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

签名算法为 sm2-sign-sm3,即对 Z 做 SM3 哈希后使用 SM2 签名。

核心算法验证

SM4-CTR 加密验证

SM4-CTR 是 GM/T 0129-2023 推荐的会话加密模式。以下代码验证加解密的正确性:

运行输出

CODE
明文:  48656c6c6f2c20474d20535348207465737420646174612121
密文:  dd89efa1123c2beff77b5bc9bc7d18a8d4b02ffc3332cbce0c
解密:  48656c6c6f2c20474d20535348207465737420646174612121

SM3-KDF 密钥派生验证

以下代码演示从共享秘密派生会话密钥的 KDF 流程(基于 SM3 的简化实现):

运行输出

CODE
Key material length: 128
Key material hex: baf91f257f0aae697abfb7cb6e92f347a8799b4fb8fa7e822a6104118a7530b06e5fdf7012acb06a6bf713b40327030c45d2c0ea4122fc6f19f9f74caba3e8d1763947ff743422d7c55bc98cafc4af043d72a333576c79f1ffcae785e4aaedd6115917f6e35ac243605a45957aa853d069d11c2f9954e3bb0c4aec36272df0f9

部署实战

环境要求

组件推荐版本获取方式
Tongsuo8.4.xhttps://github.com/Tongsuo-Project/Tongsuo
OpenSSH9.x + 国密补丁https://github.com/Tongsuo-Project/OpenSSH
操作系统CentOS 7+/Ubuntu 20.04+

编译部署 Tongsuo

BASH
# 克隆并编译 Tongsuo
git clone https://github.com/Tongsuo-Project/Tongsuo.git
cd Tongsuo
./config --prefix=/opt/tongsuo --libdir=lib
make -j$(nproc)
sudo make install

# 验证安装
/opt/tongsuo/bin/openssl version
# 预期输出:Tongsuo 8.x.x

编译部署国密 OpenSSH

生成国密主机密钥

BASH
# 生成 SM2 主机密钥
sudo /opt/tongsuo/bin/openssl genpkey -algorithm SM2 \
    -out /etc/ssh/ssh_host_sm2_key
sudo chmod 600 /etc/ssh/ssh_host_sm2_key

# 查看公钥
sudo /opt/tongsuo/bin/openssl pkey -in /etc/ssh/ssh_host_sm2_key \
    -pubout -out /etc/ssh/ssh_host_sm2_key.pub

sshd_config 配置

⚠️ 密评合规提示:如果目标是通过密评,建议移除所有国际算法,仅保留国密算法。保留国际算法会导致"算法协商不一致"扣分。生产环境中可通过独立端口(如 2222)提供纯国密 SSH,端口 22 保留国际算法兼容。

验证部署

生产注意事项

1. 前向保密

SM2 密钥交换通过临时密钥对 (rA, rB) 提供前向保密:每次会话结束后临时密钥即被销毁,即使服务器长期私钥泄露,攻击者也无法从截获的网络流量中恢复会话密钥。这与 ECDHE 的前向保密机制类似。

2. 降级攻击防护

如果 KexAlgorithms 同时包含国密和国际算法,攻击者可通过中间人篡改 KEXINIT 消息迫使双方降级到较弱的算法。建议在生产环境中:

  • 管理网段仅开放国密端口
  • sshd_config 中禁用国际算法
  • 使用 ssh -Q 定期审计算法列表

3. 兼容性处理

客户端类型兼容方案
Linux + 国密 OpenSSH原生支持 sm2-exch-sm3
PuTTY / Windows需使用 Tongsuo 编译的 PuTTY 或 OpenSSH for Windows
跳板机/堡垒机齐治、绿盟等厂商已内置国密 SSH 服务端
Ansible/SaltStack需配置 ansible_ssh_common_args 指定国密算法

4. 密钥轮换

国密主机密钥建议每年轮换一次:

5. 审计日志

BASH
# 查看所有 SSH 登录记录
sudo grep "sshd" /var/log/secure | tail -50

# 监控失败的密钥交换
sudo grep "Unable to negotiate" /var/log/secure

# 监控国密连接
sudo grep "sm2-exch-sm3" /var/log/secure

已知限制

  • 公钥格式未国际标准化:标准 OpenSSH 8.x 不理解 ssh-sm2 公钥格式,无法直接复制国密公钥到 authorized_keys
  • 证书链复杂性:SM2 数字证书遵循 GM/T 0015-2023,国际 CA 不签发,需自建国密 PKI
  • KDF 缺少域分离:与 HKDF 相比,GM/T 0129-2023 的 KDF 缺少 salt 和 info 扩展,多会话场景下需确保 session_id 唯一性
  • 后量子迁移路径不明确:SM2 基于 ECDLP,可被量子计算机破解。目前 NIST PQC 标准化的 ML-KEM(Kyber)和 SLH-DSA 尚未在 SSH 国密标准中定义

总结

GM/T 0129-2023 为国密 SSH 提供了完整的协议规范,核心要点:

  • 算法套件sm2-exch-sm3(密钥交换)+ sm4-ctr(加密)+ hmac-sm3(完整性)
  • 前向保密:通过 SM2 临时密钥对实现,每次会话独立
  • 部署路径:Tongsuo(国密 OpenSSL)+ OpenSSH 国密补丁
  • 密评合规:纯国密配置可通过密评,保留国际算法会被扣分
  • 生产建议:独立端口部署、定期密钥轮换、审计日志监控
对于等保三级系统的远程管理通道改造,国密 SSH 是必选项。建议先在测试环境完成兼容性验证(尤其是跳板机和自动化运维工具),再切生产流量。

参考来源

  • GM/T 0129-2023《SSH 密码协议规范》(国家密码管理局,2023-12 发布,2024-06-01 实施)
  • GM/T 0003.3-2012《SM2 椭圆曲线公钥密码算法 第 3 部分:密钥交换协议》
  • GM/T 0002-2012《SM4 分组密码算法》
  • RFC 4251-4253(SSH Protocol Architecture, Authentication, Transport Layer)
  • Tongsuo 项目:https://github.com/Tongsuo-Project/Tongsuo
  • GM/T 0009-2023《SM2 密码算法使用规范》