I'm creating a window service for downloading files from an SFTP server. For that I'm using Renci.SshNet
, Renci.SshNet.Common
and Renci.SshNet.Sftp
.
I have this code:
String Host = "HostName";
int Port = 22;
String RemoteFileDirectory =
Convert.ToString(ConfigurationManager.AppSettings["SourcePath"]);
String Username = "UserName";
String Password = "*******";
var KeybasedMethod = new KeyboardInteractiveAuthenticationMethod(Username);
KeybasedMethod.AuthenticationPrompt +=
(sender, e) => { e.Prompts.First().Response = password; };
AuthenticationMethod[] methods = new AuthenticationMethod[]
{
new PrivateKeyAuthenticationMethod(Username, new PrivateKeyFile(@"Z:\SFTP SETUP\CJ22")),
KeybasedMethod
};
ConnectionInfo connectionInfo = new ConnectionInfo(hostname, username, methods);
using (var sftp = new SftpClient(connectionInfo))
{
sftp.Connect();
// ...
}
I get exception.
Invalid private key file.
I can't figure it out that what I'm missing in my code.
Below is the log file I'm getting at the time when I login to server from my client machine using FileZilla.
2017-04-03 16:25:19 8120 3 Status: Connecting to abc.domainname.com...
2017-04-03 16:25:19 8120 3 Trace: Going to execute "C:\Program Files\FileZilla FTP Client\fzsftp.exe"
2017-04-03 16:25:19 8120 3 Response: fzSftp started
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectParseResponse(fzSftp started)
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectSend()
2017-04-03 16:25:19 8120 3 Command: keyfile "Z:\SFTP SETUP\CJ21_PVT.ppk"
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectParseResponse()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectSend()
2017-04-03 16:25:19 8120 3 Command: keyfile "Z:\SFTP SETUP\CJ22_PVT.ppk"
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectParseResponse()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectSend()
2017-04-03 16:25:19 8120 3 Command: keyfile "Z:\SFTP SETUP\CJ24_PVT.ppk"
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectParseResponse()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectSend()
2017-04-03 16:25:19 8120 3 Command: keyfile "Z:\SFTP SETUP\CJ90_PVT.ppk"
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectParseResponse()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:19 8120 3 Trace: CSftpControlSocket::ConnectSend()
2017-04-03 16:25:19 8120 3 Command: open "CJ22@abc.domainname.com" 22
2017-04-03 16:25:19 8120 3 Trace: Looking up host "abc.domainname.com"
2017-04-03 16:25:19 8120 3 Trace: Connecting to xxx.xxx.163.74 port 22
2017-04-03 16:25:23 8120 3 Trace: Server version: SSH-2.0-1.82_sshlib Globalscape
2017-04-03 16:25:23 8120 3 Trace: Using SSH protocol version 2
2017-04-03 16:25:23 8120 3 Trace: We claim version: SSH-2.0-PuTTY_Local:_Mar_28_2014_10:34:48
2017-04-03 16:25:24 8120 3 Trace: Doing Diffie-Hellman group exchange
2017-04-03 16:25:24 8120 3 Trace: Doing Diffie-Hellman key exchange with hash SHA-1
2017-04-03 16:25:25 8120 3 Trace: Host key fingerprint is:
2017-04-03 16:25:25 8120 3 Trace: ssh-rsa 2048 6b:80:2c:5e:af:3f:2c:c7:f7:ef:4b:dd:85:55:32:fe
2017-04-03 16:25:25 8120 3 Trace: Initialised AES-256 SDCTR client->server encryption
2017-04-03 16:25:25 8120 3 Trace: Initialised HMAC-SHA1 client->server MAC algorithm
2017-04-03 16:25:25 8120 3 Trace: Initialised AES-256 SDCTR server->client encryption
2017-04-03 16:25:25 8120 3 Trace: Initialised HMAC-SHA1 server->client MAC algorithm
2017-04-03 16:25:25 8120 3 Trace: Successfully loaded 4 key pairs from file
2017-04-03 16:25:26 8120 3 Trace: Offered public key from "Z:\SFTP SETUP\CJ21_PVT.ppk"
2017-04-03 16:25:26 8120 3 Trace: Server refused public key
2017-04-03 16:25:26 8120 3 Trace: Offered public key from "Z:\SFTP SETUP\CJ22_PVT.ppk"
2017-04-03 16:25:26 8120 3 Trace: Offer of public key accepted, trying to authenticate using it.
2017-04-03 16:25:29 8120 3 Trace: Further authentication required
2017-04-03 16:25:30 8120 3 Trace: Using keyboard-interactive authentication. inst_len: 0, num_prompts: 1
2017-04-03 16:25:30 8120 3 Command: Pass: *********
2017-04-03 16:25:30 8120 3 Trace: Access granted
2017-04-03 16:25:30 8120 3 Trace: Opened channel for session
2017-04-03 16:25:31 8120 3 Trace: Started a shell/command
2017-04-03 16:25:31 8120 3 Status: Connected to abc.domainname.com
2017-04-03 16:25:33 8120 3 Trace: CSftpControlSocket::ConnectParseResponse()
2017-04-03 16:25:33 8120 3 Trace: CSftpControlSocket::ResetOperation(0)
2017-04-03 16:25:33 8120 3 Trace: CControlSocket::ResetOperation(0)
2017-04-03 16:25:33 8120 3 Trace: CFileZillaEnginePrivate::ResetOperation(0)
2017-04-03 16:25:33 8120 3 Status: Retrieving directory listing...
2017-04-03 16:25:33 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:33 8120 3 Trace: CSftpControlSocket::ChangeDirSend()
2017-04-03 16:25:33 8120 3 Command: cd "/"
2017-04-03 16:25:34 8120 3 Response: New directory is: "/"
2017-04-03 16:25:34 8120 3 Trace: CSftpControlSocket::ResetOperation(0)
2017-04-03 16:25:34 8120 3 Trace: CControlSocket::ResetOperation(0)
2017-04-03 16:25:34 8120 3 Trace: CSftpControlSocket::ParseSubcommandResult(0)
2017-04-03 16:25:34 8120 3 Trace: CSftpControlSocket::ListSubcommandResult()
2017-04-03 16:25:34 8120 3 Trace: state = 1
2017-04-03 16:25:34 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:34 8120 3 Trace: CSftpControlSocket::ListSend()
2017-04-03 16:25:34 8120 3 Trace: state = 2
2017-04-03 16:25:34 8120 3 Command: ls
2017-04-03 16:25:34 8120 3 Status: Listing directory /
2017-04-03 16:25:36 8120 3 Listing: drwxrw-rw- 1 user group 0 Mar 24 2015 JKOB1
2017-04-03 16:25:36 8120 3 Listing: drwxrw-rw- 1 user group 0 Apr 3 10:40 JKOB
2017-04-03 16:25:36 8120 3 Trace: CSftpControlSocket::ListParseResponse()
2017-04-03 16:25:36 8120 3 Trace: CSftpControlSocket::SendNextCommand()
2017-04-03 16:25:36 8120 3 Trace: CSftpControlSocket::ListSend()
2017-04-03 16:25:36 8120 3 Trace: state = 3
2017-04-03 16:25:36 8120 3 Status: Calculating timezone offset of server...
2017-04-03 16:25:36 8120 3 Command: mtime "JKOB"
2017-04-03 16:25:37 8120 3 Response: 1491216040
2017-04-03 16:25:37 8120 3 Trace: CSftpControlSocket::ListParseResponse(1491216040)
2017-04-03 16:25:37 8120 3 Status: Timezone offsets: Server: 0 seconds. Local: 19800 seconds. Difference: 19800 seconds.
2017-04-03 16:25:37 8120 3 Trace: CSftpControlSocket::ResetOperation(0)
2017-04-03 16:25:37 8120 3 Trace: CControlSocket::ResetOperation(0)
2017-04-03 16:25:37 8120 3 Status: Directory listing successful
2017-04-03 16:25:37 8120 3 Trace: CFileZillaEnginePrivate::ResetOperation(0)
2017-04-03 16:27:24 8120 3 Status: Disconnected from server
2017-04-03 16:27:24 8120 3 Trace: CControlSocket::DoClose(64)
2017-04-03 16:27:24 8120 3 Trace: CSftpControlSocket::ResetOperation(66)
2017-04-03 16:27:24 8120 3 Trace: CControlSocket::ResetOperation(66)
2017-04-03 16:27:24 8120 3 Trace: CFileZillaEnginePrivate::ResetOperation(66)
2017-04-03 16:27:24 8120 3 Trace: CControlSocket::DoClose(64)
2017-04-03 16:27:24 8120 3 Trace: CControlSocket::DoClose(64)
2017-04-03 16:27:24 8120 3 Trace: CFileZillaEnginePrivate::ResetOperation(0)
I've tried multiple solution from here and from other sources one after another but none of them worked. If you've any suggestion then it's more than welcome.
SSH.NET does not support .ppk key files. You have to use PuTTYgen to convert the .ppk key to OpenSSH format.
Original answer, before the question was edited:
You are using multifactor private key and keyboard interactive authentication in FileZilla:
2017-04-03 16:25:26 8120 3 Trace: Offered public key from "Z:\SFTP SETUP\CJ22_PVT.ppk"
2017-04-03 16:25:26 8120 3 Trace: Offer of public key accepted, trying to authenticate using it.
2017-04-03 16:25:29 8120 3 Trace: Further authentication required
2017-04-03 16:25:30 8120 3 Trace: Using keyboard-interactive authentication. inst_len: 0, num_prompts: 1
2017-04-03 16:25:30 8120 3 Command: Pass: *********
2017-04-03 16:25:30 8120 3 Trace: Access granted
While, you are using simple password authentication in your code:
using (var sftp = new SftpClient(Host, Port, Username, Password))
How can you even expect this to work?
To implement multifactor authentication, you have to use ConnectionInfo
.
var keybInterMethod = new KeyboardInteractiveAuthenticationMethod(username);
keybInterMethod.AuthenticationPrompt +=
(sender, e) => { e.Prompts.First().Response = password; };
AuthenticationMethod[] methods = new AuthenticationMethod[] {
new PrivateKeyAuthenticationMethod(username, new PrivateKeyFile(privateKey)),
keybInterMethod
};
ConnectionInfo connectionInfo = new ConnectionInfo(hostname, username, methods);
using (var sftp = new SftpClient(connectionInfo))
{
sftp.Connect();
// ...
}