Search code examples
c#.netsshssh.net

Retrieve host fingerprint without authenticating?


Is there any way I can retrieve the remote host fingerprint without having to pass credentials or otherwise authenticating to the device?

There is an ssh.net example where it shows how to validate a host fingerprint but it requires credentials. There's no constructor for the SshClient that doesn't take a username and even the ConnectionInfo class requires one as well so I'm not sure how to best proceed.

There's not a lot of documentation although I did find the NuDoq repository but this class is pretty big and the examples are limited so any point in the right direction is appreciated!

This is the example they gave but it requires authentication:

byte[] expectedFingerPrint =
    new byte[] {
        0x66, 0x31, 0xaf, 0x00, 0x54, 0xb9, 0x87, 0x31,
        0xff, 0x58, 0x1c, 0x31, 0xb1, 0xa2, 0x4c, 0x6b
    };

using (var client = new SshClient("sftp.foo.com", "guest", "pwd"))
{
    client.HostKeyReceived += (sender, e) =>
        {
            if (expectedFingerPrint.Length == e.FingerPrint.Length)
            {
                for (var i = 0; i < expectedFingerPrint.Length; i++)
                {
                    if (expectedFingerPrint[i] != e.FingerPrint[i])
                    {
                        e.CanTrust = false;
                        break;
                    }
                }
            }
            else
            {
                e.CanTrust = false;
            }
        };
    client.Connect();
}

Solution

  • HostKeyReceived happens before any authentication. Host key must be verified before authenticating, so that the client does not inadvertently send credentials to malicious server or MITM.

    So the credentials do not matter. Just provide dummy credentials in the constructor, check the fingerprint in your event handler, and abort the connection.