ssh协议分析及国产化替代
SSH 协议建立过程
TCP 连接
客户端连接服务器 22 端口。版本交换(明文)
双方互发 SSH 协议版本,如 SSH-2.0-OpenSSH_9.9。算法协商(明文)
双方各自发送 SSH_MSG_KEXINIT,列出支持的:- 密钥交换算法 KEX
- 主机密钥算法
- 对称加密算法
- MAC 算法
双方协商出一组共同支持的算法。
密钥交换(临时密钥)
客户端生成临时密钥对 (a, A),发送 A。
服务器生成临时密钥对 (b, B),发送 B。
双方各自计算共享秘密:
客户端:K = a * B
服务器:K = b * A
两者得到相同的 K。
临时私钥不发送,用完即弃。交换哈希与服务器签名(长期主机密钥)
双方计算:
H = hash(V_C, V_S, I_C, I_S, K_S, A, B, K)
其中 K_S 是服务器长期主机公钥。
服务器用长期主机私钥对 H 签名,发送签名。
客户端用 known_hosts 中的服务器主机公钥验签。
验签通过 → 确认服务器身份,且交换内容未被篡改。
验签失败 → 中断连接,提示主机密钥变更或中间人攻击。派生会话密钥(本地计算,不发送)
双方各自执行:
会话密钥 = KDF(K, H, 会话ID, 标签, 长度)
派生出的密钥双向独立:- 客户端到服务器:加密密钥、IV、MAC 密钥
- 服务器到客户端:加密密钥、IV、MAC 密钥
这些会话密钥是临时的。
SSH_MSG_NEWKEYS
双方各自发送 SSH_MSG_NEWKEYS,通知对方准备切换。
之后所有消息都用新会话密钥加密和完整性保护。用户认证(加密通道内)
- 公钥认证:用户用长期私钥签名,服务器用 authorized_keys 中的公钥验签。
- 密码认证:密码在加密通道内发送。
用户密钥只用于认证,不参与会话密钥派生。
连接层与数据传输
建立多个通道:shell、SFTP、端口转发等。
数据用对称加密保护,并用 MAC/AEAD 保证完整性。重密钥
达到数据量或时间阈值后,重新执行密钥交换,派生新会话密钥。连接关闭
发送 SSH_MSG_DISCONNECT,销毁临时密钥和会话密钥,关闭 TCP。
ssh本身的加固
# /etc/ssh/sshd_config |
一些细碎内容还可以扩展
KbdInteractiveAuthentication 即键盘交互认证 在前面的ssh协议分析时候也写过 ssh在认证时会有两种选择 一种是密钥登陆一种就是键盘认证 这里的键盘认证不知局限于密码登录 其实还有2FA等等 一般作为仅允许密钥登陆的附属设置
GatewayPorts 控制远程转发端口绑定到哪个地址 与之对应的是转发到本地
no:只绑定到回环地址(默认,最安全)。yes:绑定到通配地址,所有接口。clientspecified:由客户端指定绑定地址。
loglevel很明显就是日志记录等级LogLevel可选值从少到多大致是:
| 等级 | 含义 |
|---|---|
QUIET |
几乎不记录 |
FATAL |
只记录致命错误 |
ERROR |
只记录错误 |
INFO |
默认,记录常规信息 |
VERBOSE |
更详细,记录登录、认证、密钥指纹等 |
DEBUG / DEBUG1 |
调试级别,信息很多 |
DEBUG2 |
更详细 |
DEBUG3 |
最详细,日志量极大 |
| 加固也可以通过防火墙来限制 这里使用麒麟自带的 |
国产化的替代即用
| 阶段 | 国际算法 | 国密算法 |
|---|---|---|
| 版本交换 | 明文 | 明文 |
| 算法协商 | curve25519、ed25519、aes、hmac-sha2 | sm2-sm3、sm2、sm4-ctr、hmac-sm3 |
| 密钥交换 | ECDH / DH | SM2 密钥交换 |
| 交换哈希 | SHA-256 | SM3 |
| 服务器签名 | Ed25519 / RSA | SM2 签名 |
| 客户端验签 | known_hosts 中国际公钥 | known_hosts 中 SM2 公钥 |
| KDF | 基于 SHA-256 | 基于 SM3 |
| 会话加密 | AES / ChaCha20 | SM4 |
| 完整性 | HMAC-SHA256 / Poly1305 | HMAC-SM3 |
| 用户认证 | Ed25519 / RSA | SM2 |
| 重密钥 | 重新 ECDH/DH | 重新 SM2 密钥交换 |
流程不变,信任模型不变:临时密钥负责机密性和前向保密,长期密钥负责身份验证和防中间人。国密改造只是把算法套件从国际标准替换为国产商用密码标准。