Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

com.jcraft.jsch.JSchException: UnknownHostKey

Tags:

java

ssh

jsch

People also ask

What is COM Jcraft JSch?

JSch is a pure Java implementation of SSH2. License.

What is JSch connection?

JSch. JSch is the Java implementation of SSH2 that allows us to connect to an SSH server and use port forwarding, X11 forwarding, and file transfer. Also, it is licensed under the BSD style license and provides us with an easy way to establish an SSH connection with Java.

What is StrictHostKeyChecking in JSch?

StrictHostKeyChecking values: ask | yes | no. default: ask. If this property is set to yes, JSch will never automatically add host keys to the $HOME/. ssh/known_hosts file, and refuses to connect to hosts whose host key has changed. This property forces the user to manually add all new hosts.


I would either:

  1. Try to ssh from the command line and accept the public key (the host will be added to ~/.ssh/known_hosts and everything should then work fine from Jsch) -OR-
  2. Configure JSch to not use "StrictHostKeyChecking" (this introduces insecurities and should only be used for testing purposes), using the following code:

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

Option #1 (adding the host to the ~/.ssh/known_hosts file) has my preference.


While the question has been answered in general, I've found myself that there's a case when even existing known_hosts entry doesn't help. This happens when an SSH server sends ECDSA fingerprint and as a result, you'll have an entry like this:

|1|+HASH=|HASH= ecdsa-sha2-nistp256 FINGERPRINT=

The problem is that JSch prefers SHA_RSA and while connecting it will try to compare SHA-RSA fingerprint, which will result with error about "unknown host".

To fix this simply run:

$ ssh-keyscan -H -t rsa example.org >> known_hosts

or complain to Jcraft about prefering SHA_RSA instead of using the local HostKeyAlgorithms setting, although they don't seem to be too eager to fix their bugs.


It is a security risk to avoid host key checking.

JSch uses HostKeyRepository interface and its default implementation KnownHosts class to manage this. You can provide an alternate implementation that allows specific keys by implementing HostKeyRepository. Or you could keep the keys that you want to allow in a file in the known_hosts format and call

jsch.setKnownHosts(knownHostsFileName);

Or with a public key String as below.

String knownHostPublicKey = "mysite.com ecdsa-sha2-nistp256 AAAAE............/3vplY";
jsch.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));

see Javadoc for more details.

This would be a more secure solution.

Jsch is open source and you can download the source from here. In the examples folder, look for KnownHosts.java to know more details.


Depending on what program you use for ssh, the way to get the proper key could vary. Putty (popular with Windows) uses their own format for ssh keys. With most variants of Linux and BSD that I've seen, you just have to look in ~/.ssh/known_hosts. I usually ssh from a Linux machine and then copy this file to a Windows machine. Then I use something similar to

jsch.setKnownHosts("C:\\Users\\cabbott\\known_hosts");

Assuming I have placed the file in C:\Users\cabbott on my Windows machine. If you don't have access to a Linux machine, try http://www.cygwin.com/

Maybe someone else can suggest another Windows alternative. I find putty's way of handling SSH keys by storing them in the registry in a non-standard format bothersome to extract.


Supply the public rsa key of the host :-

String knownHostPublicKey = "mywebsite.com ssh-rsa AAAAB3NzaC1.....XL4Jpmp/";

session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));