You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SSH.NET在无需认证的情况下获取远程主机指纹?

无需凭证获取SSH远程主机指纹的实现方案

嘿,这个问题我之前也踩过坑!答案是完全可以——SSH协议的握手流程里,主机密钥(也就是指纹的来源)是在用户认证之前就会发送的,所以根本不需要提供有效的凭证,甚至连真实的用户名都不用。

针对你提到的SSH.NET的限制(SshClient和ConnectionInfo都要求用户名),其实有个很简单的 workaround:随便填一个无效的用户名就行,比如dummy,因为在主机密钥交换阶段,服务器还不会验证你的身份,这个用户名只是个占位符,完全不影响我们获取指纹。

下面是我实测有效的代码示例,用SSH.NET实现无凭证获取主机指纹:

using Renci.SshNet;
using Renci.SshNet.Common;

public string FetchHostFingerprint(string targetHost, int port = 22)
{
    // 随便填一个占位用户名,不需要真实存在
    var placeholderUser = "dummy-user";
    // 使用None认证方法,不需要任何凭证
    var authMethod = new NoneAuthenticationMethod(placeholderUser);
    var connectionInfo = new ConnectionInfo(targetHost, port, placeholderUser, authMethod);

    try
    {
        using var sshClient = new SshClient(connectionInfo);
        
        // 监听HostKeyReceived事件,这是我们获取指纹的关键节点
        sshClient.HostKeyReceived += (sender, e) =>
        {
            // 提取主机密钥的指纹
            var fingerprintBytes = e.HostKey.GetFingerprint();
            // 标记信任该密钥(只是为了跳过后续的信任提示)
            e.CanTrust = true;
            // 立即取消后续的连接流程,因为我们只需要指纹,不需要认证
            e.Cancel = true;
        };

        // 触发连接流程,虽然会因为我们取消而抛出异常,但指纹已经拿到了
        sshClient.Connect();
    }
    catch (SshConnectionException)
    {
        // 这个异常是我们主动取消连接导致的,直接忽略即可
    }

    // 将指纹字节转换成常用的冒号分隔格式返回
    return BitConverter.ToString(connectionInfo.HostKey.GetFingerprint()).Replace("-", ":");
}

关键细节说明:

  • NoneAuthenticationMethod:这是SSH.NET专门提供的无认证方法,刚好匹配我们不需要凭证的场景
  • HostKeyReceived事件:这个事件会在服务器发送主机密钥后立刻触发,此时还没到用户认证环节,所以我们能轻松拿到指纹
  • 主动取消连接:拿到指纹后直接取消后续流程,避免不必要的认证尝试,也节省资源

本质上,我们是利用了SSH协议的握手顺序:主机密钥交换 → 用户认证 → 会话建立。我们只需要走到第一步就停下来,完全不需要涉及后续的认证步骤。

内容的提问来源于stack exchange,提问作者Brian Mitchell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:13:26