Search code examples
apache-cameljschcamel-ftp

Camel SFTP connection jcraft jsch exception


I am using camel version 2.13.1,and camel-ftp version 2.13.1. I am trying to connect to sftp server through camel route. I am getting some error related to jCraft Jsch exception as shown below.

org.apache.camel.component.file.GenericFileOperationFailedException: Cannot connect to sftp://uname@serveraddress.com:22
    at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:143)
    at org.apache.camel.component.file.remote.RemoteFileConsumer.connectIfNecessary(RemoteFileConsumer.java:154)
    at org.apache.camel.component.file.remote.RemoteFileConsumer.recoverableConnectIfNecessary(RemoteFileConsumer.java:145)
    at org.apache.camel.component.file.remote.RemoteFileConsumer.prePollCheck(RemoteFileConsumer.java:55)
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:106)
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:187)
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:114)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: com.jcraft.jsch.JSchException: Algorithm negotiation fail
    at com.jcraft.jsch.Session.receive_kexinit(Session.java:582)
    at com.jcraft.jsch.Session.connect(Session.java:320)
    at org.apache.camel.component.file.remote.SftpOperations.connect(SftpOperations.java:115)
    ... 14 more

Solution

  • Judging from the exception message, it appears that there is no shared key exchange (KEX) algorithms between the client and the SSH server. You can verify this by enabling logging in JSch before you try to connect:

    JSch.setLogger(new Logger() {
        @Override
        public boolean isEnabled(int i) {
            return true;
        }
        @Override
        public void log(int i, String string) {
            System.out.println(string);
        }
    };
    

    This will output a list of KEX supported by the server and the client, respectively. For example:

    kex: server: ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1

    I would expect that you would see that none of the KEX algorithms listed by the server are in the client list. Based on that you can then either enable additional KEX algorithms on the server (provided that you have access to it), or to your client application. For more, also see this page.

    If you cannot make changes to the server, you can add support for additional KEX algorithms in one of two ways:

    1. Upgrade JSch to the latest release (0.1.52) to automatically enable support for sha256.
    2. If you're stuck with 0.1.51, you can programatically enable sha256:

      JSch shell = new JSch();
      Properties config = new Properties();
      config.put("kex", "diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,diffie-hellman-group-exchange-sha1,diffie-hellman-group-exchange-sha256");
      config.put("StrictHostKeyChecking", "no");
      

    Then create your session and set the configuration with:

    Session session = ...
    session.setConfig(config);
    

    Update: In this case, it turned out not to be a missing algorithm, but a missing cypher. The server only supported the aes256-cbc cypher, which by default is not supported by Oracle's JVM. However, it can be downloaded directly from Oracle.