Apache vfs/jsch sftp Algorithm negotiation fail

498 Views Asked by At

I'm trying to connect to a sftp server, which I connect to via commands using sftp -oHostKeyAlgorithms=+ssh-dss user@host. However, when I try to connect via my java-spring application, using apache vfs, I get the following exception:

ERROR] 20/06/2023 11:50:13.333 [http-nio-8080-exec-1]  o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: org.apache.commons.vfs2.FileSystemException: Could not connect to SFTP server at "sftp://user:***@host/".] with root cause
com.jcraft.jsch.JSchException: Algorithm negotiation fail

My file download method looks like this:

public void downloadFile(final String originFilePath, final String destinationFilePath) throws IOException {
        try (final StandardFileSystemManager manager = new StandardFileSystemManager()) {
            manager.init();
            final FileObject remoteFile = manager.resolveFile(getConnectionWithPath(originFilePath), createDefaultOptions());
            manager.resolveFile(destinationFilePath).copyFrom(remoteFile, Selectors.SELECT_SELF);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

The getConnectionWithPath(originFilePath) looks like this (the getX() methods retrieve the value from my properties file):

public String getConnectionWithPath(final String remoteFilePath) {
        return "sftp://" + getUser() + ":" + getPassword() + "@" + getIp() + "/" + remoteFilePath;
    }

And finally, my createDefaultOptions() method:

public static FileSystemOptions createDefaultOptions() throws FileSystemException {
        FileSystemOptions opts = new FileSystemOptions();

        SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, false);
        SftpFileSystemConfigBuilder.getInstance().setKeyExchangeAlgorithm(opts, "ssh-dss");
        SftpFileSystemConfigBuilder.getInstance().setDisableDetectExecChannel(opts, true);

        return opts;
    }

I'm using jsch 0.1.55 and apache vfs 2.9.0

After trying many approaches, I ended up using just jsch to create the connection and download the files I need, using the following methods:

public void downloadFile(String originFilePath, String destinationFilePath) throws IOException {
        try {
            final Session session = createSessionAndConnect();
            ChannelSftp sftpChannel = getJSCHConnectionChannel(session);

            sftpChannel.get(originFilePath, destinationFilePath);

            closeJSCHConnectionChannel(sftpChannel, session);
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        }
    }
private Session createSessionAndConnect() throws JSchException {
        JSch jsch = new JSch();
        Session session = null;

        session = jsch.getSession(getUser(), getIp(), 22);
        session.setConfig("StrictHostKeyChecking", "no"); // Is this fine?
        session.setPassword(getPassword());
        session.connect();

        return session;
    }
private ChannelSftp getJSCHConnectionChannel(Session session) throws JSchException {
        Channel channel = session.openChannel("sftp");
        channel.connect();
        return (ChannelSftp) channel;
    }
private void closeJSCHConnectionChannel(final ChannelSftp sftpChannel, final Session session) {
        sftpChannel.exit();
        session.disconnect();
    }
1

There are 1 best solutions below

0
StzEZ On

Given that I couldn't find a better approach, the cose that worked for me is as follows:

I ended up using just jsch to create the connection and download the files I need, using the following methods:

public void downloadFile(String originFilePath, String destinationFilePath) throws IOException {
        try {
            final Session session = createSessionAndConnect();
            ChannelSftp sftpChannel = getJSCHConnectionChannel(session);

            sftpChannel.get(originFilePath, destinationFilePath);

            closeJSCHConnectionChannel(sftpChannel, session);
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        }
    }
private Session createSessionAndConnect() throws JSchException {
        JSch jsch = new JSch();
        Session session = null;

        session = jsch.getSession(getUser(), getIp(), 22);
        session.setConfig("StrictHostKeyChecking", "no"); // Is this fine?
        session.setPassword(getPassword());
        session.connect();

        return session;
    }
private ChannelSftp getJSCHConnectionChannel(Session session) throws JSchException {
        Channel channel = session.openChannel("sftp");
        channel.connect();
        return (ChannelSftp) channel;
    }
private void closeJSCHConnectionChannel(final ChannelSftp sftpChannel, final Session session) {
        sftpChannel.exit();
        session.disconnect();
    }