Wednesday, November 3, 2021

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

Issue

I am using JSch to deploy various files over multiple VPS's. I was able to get a working prototype with StrictHostKeyChecking turned off. I would now like to re-enable host key checking so that I am not vulnerable to MITM attacks. Currently, the client is a Windows machine connecting to a VPS running Debian. Here is what I have done so far:

  1. Added remote IP address on my local machine (Windows client) using "ssh-keyscan -t rsa <serverIp> >> ~/.ssh/known_hosts"
  2. Passed the path to my known_hosts file to JSch.setKnownHosts in my application.

When attempting to establish a connection, the result is

com.jcraft.jsch.JSchException: UnknownHostKey: . RSA key fingerprint is

This is obviously due to my lack of understanding on how host keys work, or cryptography for that matter. From my basic understanding, the known_hosts file contains a key. That key is used to ensure that the remote IP that we are connecting to is who they say they are, therefore preventing anyone attempting to "spoof" themselves as the server.

My known_hosts file looks like

184.154.70.174 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDNv4m+tOZUipp8UDGrd+kbtsM5R+tu3ZYZi3p7OTRWUX/Wqy74pONlLqI+/WGu77EHnOfdssJfclgo37vKLRFKneXZNAMXE7FUu5yUNOHlpPwzmvYUT/sp1k9CeNrtJAbkm05pOBIDqDQQGfQ+IAw9zqqo/sqJ6c8NKiVFAt4Ud0msvedb559dhYgcjwb52ABbsJ0mZ8FnU7LKG1592/ZTtYxam+M3qMhtJacrh5gpfZjjx2lGhqpOgvM+xwWeK6DQVn0QyIJd474G3gcm4M43ErRfzXOum3p/0wOw+hL1ora9eWSz2Wf9WuDXf86xkbZPD7Gy6ER5LBhquy331p7X

And my code is (SSH is an instance of JSch):

try {
    SSH.setKnownHosts(new FileInputStream("C:/Users/nvulc/.ssh/known_hosts"));
    SSH.addIdentity(keyPath, keyPass);
    Session session = SSH.getSession("root", "184.154.70.174", 22);
    session.connect();
} catch (Exception e) {
    e.printStackTrace();
}

Which results in:

    com.jcraft.jsch.JSchException: UnknownHostKey: 184.154.70.174. RSA key fingerprint is b4:79:5a:58:d3:15:ad:a9:c7:af:cc:d7:09:f5:40:62
    at com.jcraft.jsch.Session.checkHost(Session.java:805)
    at com.jcraft.jsch.Session.connect(Session.java:345)
    at com.jcraft.jsch.Session.connect(Session.java:183)
    at Main.main(Main.java:40)

Solution

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 only UTF-16 or even worse.

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



Answered By - Martin Prikryl