skip to Main Content

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)

2

Answers


  1. Your approach is correct and should work if done correctly. Although FYI it doesn’t entirely protect from MitM — ssh-keyscan itself uses an unverified connection and is vulnerable to MitM, although if that connection is legit, checking the key prevents faking on later connections. This is a form/variant of SSH’s common ‘ToFU’ (Trust on First Use) security model.

    From my basic understanding, the known_hosts file contains a key. …

    In general, known_hosts contains a mapping from host identities (names and/or IP addresses) to keys. But if your file was created only as you show, it has only one mapping entry containing only one key.

    1. make sure you pass the correct path to setKnownHosts, and run as the correct (same) user. If the path you specify cannot be opened (either does not exist or access not allowed) Jsch does NOT throw any error, it just returns without loading anything. You might instead open the file yourself with new FileInputStream(pathstring) and pass to the setKnownHosts(InputStream) overload, so you get an exception if the open fails.

    2. make sure you are using the same host identity. If e.g. a host has multiple names (like cloud servers often do) and you use one in ssh-keyscan but a different one in JSch then even though this is actually the same host and key it won’t match. But if you are actually using IP addresses in both places, at least if you mean IPv4, this is less likely because very few machines today have multiple public IPv4 addresses. (In the past this was more common and called multihoming.) IPv6 is more possible; most IPv6 machines have both transient and permanent public addresses (as well as local/private ones), and often multiple transients.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search