RSA 证书认证在 OpenSSH 8.2+ 上全面失效:russh 库 0.59 版本暴露双重协议编码缺陷
基于 Rust 的 SSH 客户端库 russh 0.59 版本存在一个关键协议缺陷,导致使用 RSA 私钥、SSH Agent 或 OpenSSH 证书的客户端,在配置严格的新版 OpenSSH 服务器上全面认证失败。问题的核心在于,自 OpenSSH 8.2 起,服务器默认禁用了不安全的 `ssh-rsa` (SHA-1) 算法,仅接受更安全的 `rsa-sha2-256` 或 `rsa-sha2-512`。然而,russh 库的认证逻辑未能正确适配这一变更,在三条关键认证路径上均存在协商漏洞。
具体而言,在普通私钥和 SSH Agent 认证路径中,russh 未能根据服务器支持的签名算法列表进行正确的算法协商。修复方案要求客户端必须按照 `sha2-512` → `sha2-256` → `ssh-rsa` 的顺序进行降级尝试,并在服务器明确拒绝时停止。更具隐蔽性的缺陷出现在证书认证路径。russh 暴露的 `authenticate_certificate_with` API 虽然允许传入哈希算法,但其在编码认证请求时,外层的算法名称字段被硬编码为 `[email protected]`。
这一硬编码行为直接触发了 OpenSSH 服务器的拒绝机制。服务器的真实逻辑是:首先检查外层算法名,如果不被允许(如默认禁用的 `ssh-rsa` 系列),则直接拒绝整个请求,根本不会验证证书内部签名所使用的哈希算法。这意味着,即使客户端使用 SHA-256 签名,只要外层算法名错误,认证就会在握手阶段立即失败。这一设计暴露了 russh 库在协议实现细节上的疏漏,对依赖该库构建 SSH 客户端工具(如 OxideTerm)的开发者构成了直接的兼容性风险,迫使他们必须深入协议层进行修复。