SFTP in Java

There are several free libraries to perform connections via FTP in Java (such as Sun SDK, Apache Commons Net, …). However, these ones doesn’t support SSH connections. In order to use this kind of connections, few alternatives can be found.

I’m using J2SSH project which is an abandoned software which later evolved in J2SSH-Maverick commercial package.

Connecting a server through ip address and port 22 with user/password authentication can be done as follows.

import java.util.List;

import com.sshtools.j2ssh.SftpClient;
import com.sshtools.j2ssh.SshClient;
import com.sshtools.j2ssh.authentication.AuthenticationProtocolState;
import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;
import com.sshtools.j2ssh.sftp.SftpFile;

private static final String LOGS_APPS = "/logs";
private static final String USERNAME = "user";
private static final String PASSWORD = "pass";

// Connect
SshClient ssh = new SshClient();
ssh.connect("127.0.0.1", 22, new AlwaysAllowingConsoleKnownHostsKeyVerification());

// Authenticate
PasswordAuthenticationClient passwordAuthenticationClient =
    new PasswordAuthenticationClient();
passwordAuthenticationClient.setUsername(USERNAME);
passwordAuthenticationClient.setPassword(PASSWORD);

int result = ssh.authenticate(passwordAuthenticationClient);
if(result != AuthenticationProtocolState.COMPLETE){
     throw new Exception("Login failed");
}

// Open the SFTP channel
SftpClient client = ssh.openSftpClient();

// List log directory
client.cd(LOGS_APPS);
List ls = client.ls();

...

I’ve also included AlwaysAllowingConsoleKnownHostsKeyVerification class in order to avoid user interaction required to accept connections to unknown hosts.

import com.sshtools.j2ssh.transport.ConsoleKnownHostsKeyVerification;
import com.sshtools.j2ssh.transport.InvalidHostFileException;
import com.sshtools.j2ssh.transport.publickey.SshPublicKey; 

public class AlwaysAllowingConsoleKnownHostsKeyVerification extends
        ConsoleKnownHostsKeyVerification { 

    public AlwaysAllowingConsoleKnownHostsKeyVerification()
            throws InvalidHostFileException {
        super();
        // Don't not do anything else
    } 

    @Override
    public void onHostKeyMismatch(String s, SshPublicKey sshpublickey,
            SshPublicKey sshpublickey1) {
        try
        {
            System.out.println("The host key supplied by " + s + " is: " +
                sshpublickey1.getFingerprint());
            System.out.println("The current allowed key for " + s + " is: " +
                sshpublickey.getFingerprint());
            System.out.println("Using Custom Key verification, " +
                "allowing to pass through");
            allowHost(s, sshpublickey, false);
        }
        catch(Exception exception)
        {
            exception.printStackTrace();
        }
    } 

    @Override
    public void onUnknownHost(String s, SshPublicKey sshpublickey) {
        try
        {
            System.out.println("The host " + s +
                " is currently unknown to the system");
            System.out.println("The host key fingerprint is: " +
                sshpublickey.getFingerprint());
            System.out.println("Using Custom Key verification, " +
                "allowing to pass through~~~");
            allowHost(s, sshpublickey, false);
        }
        catch(Exception exception)
        {
            exception.printStackTrace();
        }
    } 

}
  • FTPS is ftp over a SSL (secure sockets layer) connection.
  • SFTP is not ftp but SCP (secure copy) commands (or similar) over a SSH2 (secure shell) connection.

In j2ssh 0.2.9 com.sshtools.j2ssh.transport.IgnoreHostKeyVerification class can be used to perform the same operation described in the given example ( AlwaysAllowingConsoleKnownHostsKeyVerification)