com.jcraft.jsch.JSchException: UnknownHostKey



Я пытаюсь использовать 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);
}
}
}
659   12  

12 ответов:

Я:

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

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

Вариант #1 (Добавление хоста в ) и мои предпочтения.

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

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

jsch.setKnownHosts(knownHostsFileName);

или со строкой открытого ключа, как показано ниже.

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

посмотреть документация для более подробной информации.

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

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

хотя вопрос был дан ответ в целом, я обнаружил, что есть случае когда даже существующие если вы запись не поможет. Это происходит, когда 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 установка, хотя они, кажется, не слишком готовностью исправить их ошибки.

В зависимости от того, какую программу вы используете для 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 putty, сохраняя их в реестре в нестандартном формате, который надоедает извлекать.

укажите открытый ключ rsa хоста: -

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

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

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

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;
        }
    }
}

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

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

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

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

просто замените "user", "pass", "SSHD_IP". И создать файл если вы.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);
    }
  }
}

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

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

 ssh -v [email protected]
 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 [email protected] [email protected]
 debug1: kex: client->server aes128-ctr [email protected] [email protected]
 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

и не в моих окнах дома под\C:\Usersmy_local_user\.ssh, я просто объединил их и выровнял для решения проблемы.

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

кто-нибудь смог решить эту проблему? Я использую Jscp для файлов scp с использованием открытого ключа аутентификация (я не хочу использовать аутентификацию паролем). Помощь будет оценена по достоинству!!!

эта запись stackoverflow касается проверки ключа хоста, и нет никакой связи с аутентификацией открытого ключа.

что касается аутентификации с открытым ключом, попробуйте следующий пример С вашим простым (не зашифрованным) закрытым ключом,

установка известного хоста лучше, чем установка значения печати fingure.

когда вы устанавливаете известный хост, попробуйте вручную ssh (в первый раз, перед запуском приложения) из окна, в котором работает приложение.

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");
}
}

Comments

    Ничего не найдено.