Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking SFTP/SSH fingerprint in SSH.NET

I'm currently creating an SSIS package where I need to connect to a secure server to copy some files and I would like to validate the connection via the public key fingerprint the server sends.

I'm not very familiar in this area, can I always expect there to be a fingerprint sent when connecting?

The package previously used WinSCP, and a fingerprint was baked into the code in the format of ssh-dss 1024 [hex representation]. I assume this format is taken from PuTTY, because that's how I see it while connecting to a new server and it's asking me to verify. WinSCP took this as is and handled the verification.

I'm planning to switch to SSH.NET and its mechanism requires me to check the fingerprint by hand. Can I verify the connection based on just the hex, or do I need to also check the key length and the algorithm used?

like image 962
romeozor Avatar asked Aug 11 '15 11:08

romeozor


People also ask

How do I find my SFTP fingerprint?

The quickest way to obtain it would be to login to your SSH/SFTP server from a locally installed client application, i.e. installed on the same machine as your server. That way, you can be absolutely sure you're safe from man-in-the-middle attacks. Copy that fingerprint and save it where you can easily access it.

How do I confirm my SSH fingerprint?

Use ssh-keygen The -l option lists the fingerprint, and the -f /etc/ssh/ssh_host_rsa_key. pub option gives the location of the public key file of the host. That location is the default for Linux® servers, but you might need to find it in a different location.

What is server fingerprint in SFTP adapter?

Each SFTP host has one unique key used to encrypt the connection. The key has a unique “fingerprint”. The fingerprint can be entered as a series of hexadecimal numbers separated by colons. Contact your SFTP server's administrator to provide the fingerprint of the server.


2 Answers

You can do it just based on the hex - first you'll want to write (or copy/use) a utility method to convert your hex string to a byte array (which will depend on the format of your hex string) - the example below is for converting a string delimited by colon (e.g. "1d:c1:5a:71:c4:8e:a3:ff:01:0a:3b:46:17:6f:e1:52")

public static byte[] ConvertFingerprintToByteArray( String fingerprint )
{
    return fingerprint.Split( ':' ).Select( s => Convert.ToByte( s, 16 ) ).ToArray();
}

Then you simply attach to the HostKeyReceived event of the SftpClient object.

SftpClient sftpClient = new SftpClient( Hostname, Username, Password );
sftpClient.HostKeyReceived += delegate ( object sender, HostKeyEventArgs e )
{
    var b = ConvertFingerprintToByteArray(
        "1d:c1:5a:71:c4:8e:a3:ff:01:0a:3b:46:17:6f:e1:52" );
    if( e.FingerPrint.SequenceEqual( b ) )
        e.CanTrust = true;
    else
        e.CanTrust = false;
};

If this check fails then SSH.NET will throw an SshConnectionException – with a message of "Key exchange negotiation failed".

Hope this helps.

like image 187
ViniH Avatar answered Sep 18 '22 12:09

ViniH


The answer by @ViniH was correct once, but it is outdated now. Nowadays, you need to use SHA-256 hashes, not MD5. To compute the SHA-256, you can use System.Security.Cryptography.SHA256Managed class with HostKeyEventArgs.HostKey.

Further, you may want to use Convert.ToBase64String to get the common Base64 representation of the SHA-256 fingerprint

sftpClient.HostKeyReceived += (object sender, HostKeyEventArgs e) =>
{
    string sha256Fingerprint =
        Convert.ToBase64String(new SHA256Managed().ComputeHash(e.HostKey));
    e.CanTrust = (sha256Fingerprint == "1hI1HqP3IzoOWCABHGS7+GsrP2JUVsSs7oskK7HGP1E=");
};
like image 39
Martin Prikryl Avatar answered Sep 22 '22 12:09

Martin Prikryl