How to resolve Java UnknownHostKey, while using JSch SFTP library?

Caffeinated picture Caffeinated · Sep 29, 2015 · Viewed 30.4k times · Source

I'm running a java program where I transfer a file from one folder to another, using Java SFTP. The problem I'm having is that I'm getting the following error in my Java SFTP (using JSch) :

C:\Oracle\Middleware\Oracle_Home\oracle_common\jdk\bin\javaw.exe -server -classpath C:\JDeveloper\mywork\Java_Hello_World.adf;C:\JDeveloper\mywork\Java_Hello_World\Client\classes;C:\Users\ADMIN\Downloads\jsch-0.1.53.jar -Djavax.net.ssl.trustStore=C:\Users\IBM_AD~1\AppData\Local\Temp\trustStore5840796204189742395.jks FileTransfer com.jcraft.jsch.JSchException: UnknownHostKey: 127.0.0.1. RSA key fingerprint is a2:39:3f:44:88:e9:1f:d7:d1:71:f4:85:98:fb:90:dc at com.jcraft.jsch.Session.checkHost(Session.java:797) at com.jcraft.jsch.Session.connect(Session.java:342) at com.jcraft.jsch.Session.connect(Session.java:183) at FileTransfer.main(FileTransfer.java:33) Process exited with exit code 0.

The following is my code so far:

FileTransfer fileTransfer = new FileTransfer();              

JSch jsch = new JSch();

try {

    String host = "127.0.0.1";
    int port = 22;

    String user = "user";
    Session session = jsch.getSession(user, host, port);      
    session = jsch.getSession("username", "127.0.0.1", 22);
    session.connect();  // bug here , java.net.ConnectException

    ChannelSftp sftp = null;
    sftp = (ChannelSftp)session.openChannel("sftp") ; //channel;

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

    sftp.rename("C:\\Users\\ADMIN\\Desktop\\Work\\ConnectOne_Bancorp\\Java_Work\\SFTP_1\\house.bmp", "C:\\Users\\ADMIN\\Desktop\\Work\\ConnectOne_Bancorp\\Java_Work\\SFTP_2\\house.bmp");  
    session.disconnect();

} catch (JSchException e) {
    e.printStackTrace();  
} catch (SftpException e) {
    e.printStackTrace();
} //end-catch

My Cygwin is set up, and I checked (with netstat -a -b ) that it's running.

Answer

Martin Prikryl picture Martin Prikryl · Sep 30, 2015

You are trying to skip a host key checking by setting StrictHostKeyChecking to no.

But you have to do that before the checking, i.e. before the session.connect().


Anyway, you should never do this, unless you do not care about security. The host key checking is there to protect you from man-in-the-middle attacks.

Instead, set up an expected host key to let JSch verify it.

For example:

  • Call JSch.setKnownHosts providing a path to a .ssh/known_hosts-like file.

    To generate the .ssh/known_hosts-like file, you can use an ssh-keyscan command from OpenSSH. If you are connecting from a *nix server, you should have the command available, just run

    ssh-keyscan example.com > known_hosts
    

    It will have a format like:

    example.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0hVqZOvZ7yWgie9OHdTORJVI5fJJoH1yEGamAd5G3werH0z7e9ybtq1mGUeRkJtea7bzru0ISR0EZ9HIONoGYrDmI7S+BiwpDBUKjva4mAsvzzvsy6Ogy/apkxm6Kbcml8u4wjxaOw3NKzKqeBvR3pc+nQVA+SJUZq8D2XBRd4EDUFXeLzwqwen9G7gSLGB1hJkSuRtGRfOHbLUuCKNR8RV82i3JvlSnAwb3MwN0m3WGdlJA8J+5YAg4e6JgSKrsCObZK7W1R6iuyuH1zA+dtAHyDyYVHB4FnYZPL0hgz2PSb9c+iDEiFcT/lT4/dQ+kRW6DYn66lS8peS8zCJ9CSQ==
    

    And reference the generated known_hosts file in your JSch code.

    If you are on Windows, you can get a Windows build of ssh-keyscan from Win32-OpenSSH project or Git for Windows.

  • Call JSch.getHostKeyRepository().add() to provide the expected host key (e.g. hard-coded, as your other credentials).

    See Creating JSch HostKey instance from a public key in .pub format.