Connecting to a SFTP server in Java

Working in a financial environment, a lot of transfers are done using different ways.

One of these way is file transfer, usually done using FTP protocol. However FTP protocol is absolutely not secured (data and password are in clear over the network).

The operational choice is often SFTP. SFTP (SSH File Transfer Protocol) is not FTP over SSH, but a rather new protocol, designed since the beginning by working group IETF SECSH. SFTP is a communication protocol running above SSH, do not confuse with File Transfer Protocol over SSL, FTPS.

The goal of this post is to write a piece of code to connect to a SFTP server, upload a file and dlownload another file. We will of course write a unit test and for this task, we will use an embedded SFTP server.

The client : Jsch

Jsch is a 100% Java implementation of SSH2.

This library will allow us to communicate with a SFTP server. Authentication with this kind of server may done done in 2 ways (do not forget SFTP is SSH, so we will find common stuff) :

  • login and password
  • login and private key (whose public key has been previously registered on the server)

In this article, we will use login/password authentication (because it’s simpler to implement).

A SFTP server for local development

For coding, I advise you to use a little SFTP server, executed on your workstation : miniSFTPServer is a very light simple SFTP server, allowing you to work locally.

You just have to launch it, then configure a lort, a login, a password and a root path.

SFTP connection

SFTP server is now up & running : let’s start coding !

Connecting to the server is quite easy :

jsch = new JSch();
session = jsch.getSession(login, server, port);

// Java 6 version
session.setPassword(password.getBytes(Charset.forName("ISO-8859-1")));

// Java 5 version
// session.setPassword(password.getBytes("ISO-8859-1"));

Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);

session.connect();

Then, you have to add a com.jcraft.jsch.Channel of type “sftp” (which is a com.jcraft.jsch.ChannelSftp once the channel is accepted) :

// Initializing a channel
channel = session.openChannel("sftp");
channel.connect();
c = (ChannelSftp) channel;

Uploading a file

This is quite simple again : the previously created Channel gives us a method put :

c.put(sourceFile, destinationFile);

This code is using the 2-parameters version. This method exists in a lot of versions, check them to find the best one for your use case.

File downloading

Same player shoot again : the same Channel has a get method :

c.get(sourceFile, destinationFile);

Disconnection

As every Java stream, it’s important to close the Channel, then the Session in order to disconnect properly !

Unit testing : Mina SSHD

Mina project is offering a very interesting sub-module for unit testing SFTP servers : SSHD.

We will use SSHD to start an in-memory SFTP server which will enable us to test our SFTP client.

@Before

In a setUp method (annotated with @Before), we will start a org.apache.sshd.SshServer

@Before
public void setUp() throws IOException {
  // Init sftp server stuff
  sshd = SshServer.setUpDefaultServer();
  sshd.setPort(port);
  sshd.setPasswordAuthenticator(new MyPasswordAuthenticator());
  sshd.setPublickeyAuthenticator(new MyPublickeyAuthenticator());
  sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
  sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
  sshd.setCommandFactory(new ScpCommandFactory());

  sshd.start();
  ...
  ...
}

Method setUpDefaultServer() automatically preconfigures the SshServer. You just have to add the listening port, implement a very simple PasswordAuthenticator and a ,em>PublicKeyAuthenticator</em>.

Hard part is the next one : adding a ChannekSftp is not easy.

sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));

Once server is started, the unit test is very easy to write.

@After

Do not forget to shutdown the SshServer at the end of the unit tests execution :

sshd.stop();

Source Code

You can get all this code with comments and logs in a Maven project :

https://github.com/jpbriend/sftp-example

If you liked this post, you can share it with your followers or follow me on Twitter!