Com.Jcraft.Jsch.Jschexception: Unknownhostkey

com.jcraft.jsch.JSchException: UnknownHostKey

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.

JSch connection fails with UnknownHostKey even when the server's hostkey is present in the known_hosts file

Your code works for me – https://www.browxy.com/#ALIEN_137442 – It ends with "JSchException: Auth fail" – which means it gets past host key verification.

Make sure the known_hosts file is in plain ASCII encoding (or UTF-8 without BOM, which should be identical to ASCII for this kind of contents). But not UTF-8 with BOM, let alone UTF-16 or even worse.

Try also Unix line endings. Though line endings should not be an issue.

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

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.

Query regarding com.jcraft.jsch.JSchException: UnknownHostKey: x.y.com. DSA key fingerprint is ac:ew:....

I generated the RSA keys using PuTTYgen, but every time it tries to connect it gives issue with DSA fingerprint.

It seems that you believe that the host key has something to do with key pair that you use for authentication – It does not. Those are completely unrelated. Host keys are keys of the server, they are fixed, the same for all users of the server, generated when the server is installed.

For details, see my article Understanding SSH key pairs.

I believe that once you realize this and go back to all the existing questions about UnknownHostKey, they will now make more sense to you:

  • How to resolve Java UnknownHostKey, while using JSch SFTP library?
  • com.jcraft.jsch.JSchException: UnknownHostKey


Finally I tried below approach based on one of the posts. Get the session first time with StrictHostKeyChecking as no. Once done, save the result to known hosts file on the AWS server so that next time it tries to connect to Windows server it knows it is connecting to the right server.

This works, but I think I am losing the entire reason for not setting up session.setConfig("StrictHostKeyChecking", "no") and may be it is working. What is the right way to achieve this?

It's not a perfect solution, but it's acceptable.

For a perfect solution, find out the fingerprint locally on your Windows SSH server and configure your AWS Java code to expect it upfront.



Lastly, is StrictHostKeyChecking, accept-new a more secure and recommended operation for production environments instead of no?

no is not secure at all. accept-new is as good as your above solution. But JSch does not support accept-new anyway.

(it's not difficult to implement it)

JSch: UnknownHostKey exception even when the hostkey fingerprint is present in the known_hosts file

The problem is that you have added ECDSA host key to the known_hosts, as the ssh prefers that key type:

ECDSA key fingerprint is 11:5d:55:29:8a:77:d8:08:b4:00:9b:a3:61:93:fe:e5.

But JSch prefers RSA key, which it won't find in the known_hosts:

RSA key fingerprint is 50:db:75:ba:11:2f:43:c9:ab:14:40:6d:7f:a1:ee:e3


You probably need JCE to enable ECDSA In JSch.

See JSch Algorithm negotiation fail.


Or make ssh use RSA key with -o HostKeyAlgorithms=ssh-rsa.

See How can I force SSH to give an RSA key instead of ECDSA?

You can also use ssh-keyscan:

ssh-keyscan -t rsa example.com

JSch: UnknownHostKey exception when Host Key is in known_hosts AND after adding JCE

As the Q you linked says and your log shows, ecdsa-sha2-nistp256 is supported but ssh-rsa is preferred, and since the server you are connecting to obviously supports RSA, that is used. And you apparently do not have the RSA key in your known_hosts.

In addition to the easy option of getting the RSA key with ssh as in the linked Q or perhaps more easily with ssh-keyscan, a quick look at the source suggests if you do

Session.setConfig("server_host_key","ecdsa-sha2-nistp256")

before connecting it should permit only that hostkey, and assuming that's the key you have for that server in known_hosts it should work, but I haven't tested.

Aside: by "enable JCE" I assume you mean installing the JCE Unlimited Strength Jurisdiction Policy Files as described in the answer to JSch Algorithm negotiation fail . JCE itself has been included in every JRE since about 2005. Unlimited policy only helps if you need a symmetric cipher over 128 bits, as in that Q, whereas your log shows that your server agrees to AES-128.



Related Topics



Leave a reply



Submit