com.jcraft.jsch.JSchException: UnknownHostKey - PullRequest
       55

com.jcraft.jsch.JSchException: UnknownHostKey

159 голосов
/ 05 января 2010

Я пытаюсь использовать Jsch для установки SSH-соединения в Java. Мой код выдает следующее исключение:

com.jcraft.jsch.JSchException: UnknownHostKey: mywebsite.com. 
RSA key fingerprint is 22:fb:ee:fe:18:cd:aa:9a:9c:78:89:9f:b4:78:75:b4

Я не могу найти, как проверить ключ хоста в документации Jsch. Я включил свой код ниже.

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;

public class ssh {
    public static void main(String[] arg) {

        try {
            JSch jsch = new JSch();

            //create SSH connection
            String host = "mywebsite.com";
            String user = "username";
            String password = "123456";

            Session session = jsch.getSession(user, host, 22);
            session.setPassword(password);
            session.connect();

        } catch(Exception e) {
            System.out.println(e);
        } 
    }
}

Ответы [ 12 ]

203 голосов
/ 05 января 2010

Я бы либо:

  1. Попробуйте ssh из командной строки и примите открытый ключ (хост будет добавлен в ~/.ssh/known_hosts, и все должно нормально работать с Jsch) -OR-
  2. Сконфигурируйте JSch, чтобы он не использовал «StrictHostKeyChecking» (это приводит к небезопасности и должно использоваться только в целях тестирования), используя следующий код:

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

Опция №1 (добавление хоста в файл ~/.ssh/known_hosts) имеет мои предпочтения.

32 голосов
/ 24 декабря 2012

Это риск безопасности, чтобы избежать проверки ключа хоста.

JSch использует интерфейс HostKeyRepository и его реализацию по умолчанию класса KnownHosts для управления этим. Вы можете предоставить альтернативную реализацию, которая разрешает определенные ключи, реализуя HostKeyRepository. Или вы можете сохранить ключи, которые вы хотите разрешить, в файле в формате known_hosts и вызвать

jsch.setKnownHosts(knownHostsFileName);

Или с открытым ключом String, как показано ниже.

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

Подробнее см. Javadoc .

Это было бы более безопасным решением.

Jsch является открытым исходным кодом, и вы можете скачать исходный код с здесь . В папке примеров найдите файл KnownHosts.java, чтобы узнать подробности.

28 голосов
/ 27 июня 2017

Хотя на этот вопрос был дан общий ответ, я обнаружил, что есть случай , когда даже существующая запись known_hosts не помогает. Это происходит, когда сервер SSH отправляет отпечаток ECDSA, и в результате у вас будет такая запись:

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

Проблема в том, что JSch предпочитает SHA_RSA и при подключении попытается сравнить отпечаток SHA-RSA, что приведет к ошибке об "неизвестном хосте".

Чтобы исправить это, просто запустите:

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

или пожаловаться Jcraft о предпочтении SHA_RSA вместо использования локальной настройки HostKeyAlgorithms , хотя они, похоже, не слишком стремятся исправить их 1021 * ошибки .

16 голосов
/ 24 декабря 2012

В зависимости от того, какую программу вы используете для ssh, способ получения правильного ключа может отличаться. Putty (популярно в Windows) использует свой собственный формат для ключей ssh. С большинством вариантов Linux и BSD, которые я видел, вам просто нужно посмотреть в ~/.ssh/known_hosts. Я обычно ssh с машины Linux и затем копирую этот файл на машину Windows. Тогда я использую что-то похожее на

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

Предполагается, что я поместил файл в C:\Users\cabbott на моем компьютере с Windows. Если у вас нет доступа к машине с Linux, попробуйте http://www.cygwin.com/

Может быть, кто-то еще может предложить другую альтернативу Windows. Я нахожу способ замазки обработать ключи SSH путем их хранения в реестре в нестандартном формате.

10 голосов
/ 04 сентября 2015

Введите открытый ключ rsa хоста: -

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

session.setKnownHosts(new ByteArrayInputStream(knownHostPublicKey.getBytes()));
6 голосов
/ 22 января 2013

Вы также можете выполнить следующий код. Проверено и работает.

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive;
import com.jcraft.jsch.UserInfo;

public class SFTPTest {

    public static void main(String[] args) {
        JSch jsch = new JSch();
        Session session = null;
        try {
            session = jsch.getSession("username", "mywebsite.com", 22); //default port is 22
            UserInfo ui = new MyUserInfo();
            session.setUserInfo(ui);
            session.setPassword("123456".getBytes());
            session.connect();
            Channel channel = session.openChannel("sftp");
            channel.connect();
            System.out.println("Connected");
        } catch (JSchException e) {
            e.printStackTrace(System.out);
        } catch (Exception e){
            e.printStackTrace(System.out);
        } finally{
            session.disconnect();
            System.out.println("Disconnected");
        }
    }

    public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {

        @Override
        public String getPassphrase() {
            return null;
        }
        @Override
        public String getPassword() {
            return null;
        }
        @Override
        public boolean promptPassphrase(String arg0) {
            return false;
        }
        @Override
        public boolean promptPassword(String arg0) {
            return false;
        }
        @Override
        public boolean promptYesNo(String arg0) {
            return false;
        }
        @Override
        public void showMessage(String arg0) {
        }
        @Override
        public String[] promptKeyboardInteractive(String arg0, String arg1,
                String arg2, String[] arg3, boolean[] arg4) {
            return null;
        }
    }
}

Пожалуйста, подставьте соответствующие значения.

5 голосов
/ 20 июня 2014

Вы также можете просто сделать

session.setConfig("StrictHostKeyChecking", "no");

Это небезопасно, и это обходной путь, не подходящий для живой среды, поскольку он отключит всемирно известную проверку ключей хоста.

1 голос
/ 28 сентября 2016

Я потерял много времени из-за этой глупой проблемы, и я думаю, что сообщение совершенно верно: «В файле, к которому я обращаюсь, нет хоста», но вы можете иметь больше, чем файл know_host в вашей системе ( В качестве примера я использую mobaXterm, и он хранится внутри директории установки, монтируя дом из этого корня).

Если вы испытываете: это работает из командной строки, но не из приложения, попробуйте получить доступ к вашему удаленному серверу с помощью ssh и проверьте с опцией verbose -v, какой файл в настоящее время используется, например, следующим образом:

 ssh -v git@gitlab.com
 OpenSSH_6.2p2, OpenSSL 1.0.1g 7 Apr 2014
 debug1: Reading configuration data /etc/ssh_config
 debug1: Connecting to gitlab.com [104.210.2.228] port 22.
 debug1: Connection established.
 debug1: identity file /home/mobaxterm/.ssh/id_rsa type 1
 debug1: identity file /home/mobaxterm/.ssh/id_rsa-cert type -1
 debug1: identity file /home/mobaxterm/.ssh/id_dsa type -1
 debug1: identity file /home/mobaxterm/.ssh/id_dsa-cert type -1
 debug1: identity file /home/mobaxterm/.ssh/id_ecdsa type -1
 debug1: identity file /home/mobaxterm/.ssh/id_ecdsa-cert type -1
 debug1: Enabling compatibility mode for protocol 2.0
 debug1: Local version string SSH-2.0-OpenSSH_6.2
 debug1: Remote protocol version 2.0, remote software version OpenSSH_7.2p2      Ubuntu-4ubuntu2.1
 debug1: match: OpenSSH_7.2p2 Ubuntu-4ubuntu2.1 pat OpenSSH*
 debug1: SSH2_MSG_KEXINIT sent
 debug1: SSH2_MSG_KEXINIT received
 debug1: kex: server->client aes128-ctr hmac-sha1-etm@openssh.com zlib@openssh.com
 debug1: kex: client->server aes128-ctr hmac-sha1-etm@openssh.com zlib@openssh.com
 debug1: sending SSH2_MSG_KEX_ECDH_INIT
 debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
 debug1: Server host key: RSA b6:03:0e:39:97:9e:d0:e7:24:ce:a3:77:3e:01:42:09
 debug1: Host 'gitlab.com' is known and matches the RSA host key.
 debug1: Found key in /home/mobaxterm/.ssh/known_hosts:19
 debug1: ssh_rsa_verify: signature correct

как видите, ключ был найден в:

debug1: Found key in /home/mobaxterm/.ssh/known_hosts:19

а не в моем домашнем windows под C: \ Users \ my_local_user \. Ssh, я просто слил их и выровнял для решения проблемы.

Надеюсь, это поможет кому-то в будущем

1 голос
/ 13 июня 2013

Просто подставьте "user", "pass", "SSHD_IP". И создайте файл known_hosts.txt с содержимым ~ / .ssh / known_hosts сервера. Вы получите раковину.

public class Known_Hosts {
public static void main(String[] arg) {
    try {
        JSch jsch = new JSch();
        jsch.setKnownHosts("known_hosts.txt");
        Session session = jsch.getSession("user", "SSHD_IP", 22);
        session.setPassword("pass");
        session.connect();
        Channel channel = session.openChannel("shell");
        channel.setInputStream(System.in);
        channel.setOutputStream(System.out);
        channel.connect();
    } catch (Exception e) {
        System.out.println(e);
    }
  }
}
0 голосов
/ 20 декабря 2013
JSch jsch = new JSch();
Session session = null;
try {
session = jsch.getSession("user", "hostname", 22); // default
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.setPassword("password".getBytes());
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
System.out.println("Connected");
} catch (JSchException e) {
e.printStackTrace(System.out);
} catch (Exception e) {
e.printStackTrace(System.out);
} finally {
session.disconnect();
System.out.println("Disconnected");
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...