在 SSH.NET 中检查 SFTP/SSH 指纹

问题描述 投票:0回答:2

我目前正在创建一个 SSIS 包,我需要连接到安全服务器来复制一些文件,并且我想通过服务器发送的公钥指纹来验证连接。

我对这方面不是很熟悉,我是否总是期望连接时会发送指纹?

该软件包之前使用了WinSCP,并以

ssh-dss 1024 [hex representation]
的格式将指纹烘焙到代码中。我假设此格式取自 PuTTY,因为这就是我在连接到新服务器时看到的格式,并且要求我进行验证。 WinSCP 按原样接受并处理了验证。

我打算切换到SSH.NET,它的机制要求我手动检查指纹。我可以仅根据十六进制验证连接,还是还需要检查密钥长度和使用的算法?

.net security ssh ssh.net
2个回答
15
投票

您可以仅基于十六进制来完成此操作 - 首先您需要编写(或复制/使用)一个实用程序方法来将十六进制字符串转换为字节数组(这取决于十六进制字符串的格式) -下面的示例用于转换由冒号分隔的字符串(例如“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();
}

然后您只需附加到

HostKeyReceived
对象的
SftpClient
事件即可。

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;
};

如果此检查失败,则 SSH.NET 将抛出

SshConnectionException
– 并显示消息 “密钥交换协商失败”

希望这有帮助。


6
投票

@ViniH 的答案曾经是正确的,但现在已经过时了。如今,您需要使用 SHA-256 哈希值,而不是 MD5。要计算 SHA-256,您可以使用

System.Security.Cryptography.SHA256
HostKeyEventArgs.HostKey

此外,您可能需要使用

Convert.ToBase64String
获取 SHA-256 指纹的通用 Base64 表示

sftpClient.HostKeyReceived += (object sender, HostKeyEventArgs e) =>
{
    string sha256Fingerprint =
        Convert.ToBase64String(SHA256.Create().ComputeHash(e.HostKey));

    e.CanTrust =
        (sha256Fingerprint == "1hI1HqP3IzoOWCABHGS7+GsrP2JUVsSs7oskK7HGP1E=");
};

在旧版本的 .NET 中使用

new SHA256Managed().ComputeHash
代替
SHA256.HashData


如果您想比较完整的主机密钥(采用 OpenSSH

known_hosts
文件中看到的格式),只需 Base64 编码
e.HostKey
:

Convert.ToBase64String(e.HostKey)
© www.soinside.com 2019 - 2024. All rights reserved.