1

I'm using Renci.SSHNet to establish a connection to SFTP servers. I've done so without any problems but I've recently ran into a server to which I can´t establish a connection through my code.
I keep getting the following error:

No suitable authentication method found to complete authentication (publickey,keyboard-interactive).

The thing is, I know the host, user and password are correct as I can establish a connection using FileZilla. I've noticed while connecting to other servers using FileZilla that the fingerprints for the ones I can also connect to with my code are generated through RSA as opposed to the one that is giving me trouble, which is SHA2.

TL/DR: What I'm wondering is: is the Renci.SshNet.SFTP library compatible with sha-2 generated fingerprints or will I have to use another library for this?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
user6062387
  • 13
  • 1
  • 3
  • What AuthenticationMethod are you constructing your ConnectionInfo instance with? – trousyt Mar 14 '16 at 19:18
  • Are you asking about server key or user key? – Martin Prikryl Mar 14 '16 at 19:29
  • @trousyt it's done like this: public SSHFileTranferProtocol(string HostName, int Port, string UserName, string Password) { PasswordConnectionInfo connectionInfo = new PasswordConnectionInfo((HostName, Port, UserName, Password); sftp = new SftpClient(connectionInfo); sTransferResultMessage = ""; } – user6062387 Mar 15 '16 at 11:03
  • @MartinPrikryl I'm talking about the host key (server), if I'm not mistaken. – user6062387 Mar 15 '16 at 11:05

3 Answers3

1

I had a similar problem and finally managed to fix it. Below the solution:

1)Make sure following directives added to the solution

 using Renci.SshNet;
 using Renci.SshNet.Security;
 using SshNet.Security.Cryptography;

2)Create the connectionInfo object and add necessary HostKeyAlgorithms in it.

        var methods = new List<AuthenticationMethod>
           {
            new PasswordAuthenticationMethod("username", "password")
           };
        var connectionInfo = new ConnectionInfo("host", "username", methods.ToArray());
        connectionInfo.HostKeyAlgorithms.Clear();
       
        //ssh-ed25519
        connectionInfo.HostKeyAlgorithms.Add("ssh-ed25519", (data) => { return new KeyHostAlgorithm("ssh-ed25519", new ED25519Key(), data); });
        //ecdsa-sha2-nistp256
        connectionInfo.HostKeyAlgorithms.Add("ecdsa-sha2-nistp256", (data) => { return new KeyHostAlgorithm("ecdsa-sha2-nistp256", new EcdsaKey(), data); });
        //ecdsa-sha2-nistp384
        connectionInfo.HostKeyAlgorithms.Add("ecdsa-sha2-nistp384", (data) => { return new KeyHostAlgorithm("ecdsa-sha2-nistp384", new EcdsaKey(), data); });
        //ecdsa-sha2-nistp521
        connectionInfo.HostKeyAlgorithms.Add("ecdsa-sha2-nistp521", (data) => { return new KeyHostAlgorithm("ecdsa-sha2-nistp521", new EcdsaKey(), data); });
        //ssh-rsa
        connectionInfo.HostKeyAlgorithms.Add("ssh-rsa", (data) => { return new KeyHostAlgorithm("ssh-rsa", new RsaKey(), data); });
        //ssh-dss
        connectionInfo.HostKeyAlgorithms.Add("ssh-dss", (data) => { return new KeyHostAlgorithm("ssh-dss", new DsaKey(), data); });

3)Connect to desired sftp host using connectionInfo

 var sftp = new SftpClient(connectionInfo);

            using (sftp)
            {
                try
                {
                     sftp.Connect();
                     Console.WriteLine("Connected");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
0

The SSH.NET library does not support ECDSA key exchange algorithms (ecdh-sha2-*) yet (as of 2014.4.6-beta2 release).

It supports these:

  • diffie-hellman-group-exchange-sha256
  • diffie-hellman-group-exchange-sha1
  • diffie-hellman-group14-sha1
  • diffie-hellman-group1-sha1

The ecdh-sha2-*'s are commented-out, probably because the implementation is not complete/tested.


Though note that the server can support multiple algorithms and can agree on a different algorithm with different clients.

So the fact that you see an unsupported key type in the FileZilla, does not mean that the server necessarily insists on this key type.

It is clear that the server does not require ECDSA key exchange from the fact that the connection fail in the authentication phase. The authentication happens only after a successful key exchange. So your root problem is not the key exchange, but authentication.

If you need a help resolving your authentication problem, start a new question, include relevant source code, FileZilla log file and explain us what you did to setup the authentication on the server-side. A server-side log file might be helpful too.

Community
  • 1
  • 1
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Thank you very much! I'll try to get as much information together as possible, and then I'll start a new question. – user6062387 Mar 15 '16 at 12:27
0

Based on: https://github.com/sshnet/SSH.NET/blob/1d5d58e17c68a2f319c51e7f938ce6e964498bcc/src/Renci.SshNet/Security/Cryptography/RsaDigitalSignature.cs#L12

With following changes:

  • OID changed to sha2-256
  • hash changed from sha1 to sha2-256
public class RsaSha256DigitalSignature : CipherDigitalSignature, IDisposable
{
  private HashAlgorithm _hash;

  public RsaSha256DigitalSignature(RsaWithSha256SignatureKey rsaKey)
    // custom OID
    : base(new ObjectIdentifier(2, 16, 840, 1, 101, 3, 4, 2, 1), new RsaCipher(rsaKey))
  {
    // custom
    _hash = SHA256.Create();
  }

  protected override byte[] Hash(byte[] input)
  {
    return _hash.ComputeHash(input);
  }

  private bool _isDisposed;

  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if (_isDisposed)
      return;

    if (disposing)
    {
      var hash = _hash;
      if (hash != null)
      {
        hash.Dispose();
        _hash = null;
      }

      _isDisposed = true;
    }
  }

  ~RsaSha256DigitalSignature()
  {
    Dispose(false);
  }
}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31