16

Attempting to authenticate via username and privatekey only using the current SSH.NET library. I cannot get the password from the user so this is out of the question.

here is what i am doing now.

Renci.SshNet.ConnectionInfo conn = 
    new ConnectionInfo(hostName, port, username, new AuthenticationMethod[]
        {
            new PasswordAuthenticationMethod(username, ""), 
            new PrivateKeyAuthenticationMethod(username, new PrivateKeyFile[] 
                   { new PrivateKeyFile(privateKeyLocation, "") }),
        });

using (var sshClient = new SshClient(conn))
{
    sshClient.Connect();
} 

Now, if I remove the PasswordAuthenticationMethod from the AuthenticationMethod[] array I get an exception for for no suitable authentication method found. If i attempt to pass in the (hostname, port, username, keyfile2) as such

var keyFile = new PrivateKeyFile(privateKeyLocation);
var keyFile2 = new[] {keyFile};

again, no suitable method found.

It seems I have to use the ConnectionInfo object as I outlined above, but it seems that it evaluates the PasswordAuthenticationMethod and cant log in (since i don't provide a password) and never evaluates the PrivateKeyAuthMethod... is this the case? Is there some other way to authenticate with only a username or hostname and private key using SSH.NET lib?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
petey m
  • 305
  • 1
  • 4
  • 14
  • 4
    You have helped me indirectly by displaying how to combine password and private key authentication, for those very secure servers that require both. – Timo Jul 30 '19 at 13:28

3 Answers3

18

Your problem here is that you're still using a password, even though it is blank. Remove this line:

new PasswordAuthenticationMethod(username, ""), 

This works perfectly for me:

var pk = new PrivateKeyFile(yourkey);
var keyFiles = new[] { pk };

var methods = new List<AuthenticationMethod>();
methods.Add(new PrivateKeyAuthenticationMethod(UserName, keyFiles));

var con = new ConnectionInfo(HostName, Port, UserName, methods.ToArray());
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
scimino
  • 338
  • 3
  • 7
0

You need some thing like this, it works fine for me. Pay attention while creating new ConnectionInfo object I'm passing only host, port, user and auth method (No password is required); Second difference is that I'm passing single PrivateKeyFile, without empty quotes for 'Phrase' parameter;

public ConnectionInfo GetCertificateBasedConnection()
    {
        ConnectionInfo connection;
        Debug.WriteLine("Trying to create certification based connection...");
        using (var stream = new FileStream(ConfigurationHelper.PrivateKeyFilePath, FileMode.Open, FileAccess.Read))
        {
            var file = new PrivateKeyFile(stream);
            var authMethod = new PrivateKeyAuthenticationMethod(ConfigurationHelper.User, file);

            connection = new ConnectionInfo(ConfigurationHelper.HostName, ConfigurationHelper.Port, ConfigurationHelper.User, authMethod);
        }
        Debug.WriteLine("Certification based connection created successfully");
        return connection;
    }
-5

to perform private key authentication, you will also need the passphrase, which together with the private key, will allow authentication.
What is really needed is for RenciSSH to get with the times and write a publickeyauthentication method.

barry
  • 1
  • 1
    It seems as though public key authentication uses both a private and public key. It is explained further here: https://stackoverflow.com/a/53406885/3103633 – Window Nov 27 '18 at 19:37