Domanda

Sto cercando di utilizzare JSch per stabilire una connessione SSH in Java. Il mio codice produce il seguente eccezione:

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

Non riesco a trovare il modo di verificare la chiave host nella documentazione JSch. Ho incluso il mio codice qui sotto.

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);
        } 
    }
}
È stato utile?

Soluzione

I dovrebbero o:

  1. Prova a ssh dalla riga di comando e di accettare la chiave pubblica (l'host verrà aggiunto alla ~/.ssh/known_hosts e tutto dovrebbe quindi funzionare bene da JSch) -OR -
  2. Configura JSch non usa a "StrictHostKeyChecking" (questo introduce insicurezze e deve essere utilizzato solo a scopo di test), utilizzando il seguente codice:

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

Opzione 1 (aggiungendo l'host al file ~/.ssh/known_hosts) ha la mia preferenza.

Altri suggerimenti

Si tratta di un rischio per la sicurezza al fine di evitare il controllo chiave host.

JSch utilizza l'interfaccia HostKeyRepository e la sua classe KnownHosts implementazione di default per gestire questo. È possibile fornire un'implementazione alternativa che permette tasti specifici attuando HostKeyRepository. Oppure si potrebbe tenere le chiavi che si desidera consentire a un file nel known_hosts formato e call

jsch.setKnownHosts(knownHostsFileName);

O con una stringa chiave pubblica, come di seguito.

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

vedere Javadoc per maggiori dettagli.

Questa sarebbe una soluzione più sicura.

JSch è open source e si può scaricare il sorgente da qui . Nella cartella esempi, cercare KnownHosts.java per conoscere maggiori dettagli.

Mentre la questione è stata risolta in generale, mi sono scoperto che c'è una caso quando anche esistente known_hosts di entrata non aiuta. Ciò accade quando un server SSH invia ECDSA impronte digitali e, di conseguenza, avrete una voce come questa:

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

Il problema è che JSch preferisce SHA_RSA e durante la connessione cercherà di confrontare SHA-RSA di impronte digitali, che si tradurrà con l'errore su "host sconosciuto".

Per risolvere il problema basta eseguire:

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

o si lamentano per Jcraft circa preferendo SHA_RSA invece di utilizzare il locale di HostKeyAlgorithms impostazione, anche se non sembrano essere troppo desiderosi per correggere i bug loro .

A seconda di quale programma si usa per ssh, il modo per ottenere la chiave corretta potrebbe variare. Putty (popolare con Windows) utilizza un proprio formato per le chiavi SSH. Con la maggior parte delle varianti di Linux e BSD che ho visto, basta guardare in ~/.ssh/known_hosts. Io di solito ssh da una macchina Linux e quindi copiare questo file per una macchina Windows. Poi io uso qualcosa di simile a

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

Supponendo che ho messo il file in C:\Users\cabbott sulla mia macchina Windows. Se non si ha accesso ad una macchina Linux, prova a http://www.cygwin.com/

Forse qualcun altro può suggerire un'altra alternativa di Windows. Trovo modo di gestire chiavi SSH memorizzandoli nel Registro di sistema in un formato non standard fastidio per estrarre di stucco.

Fornire la chiave RSA pubblica del paese ospitante: -

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

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

È inoltre possibile eseguire il codice seguente. E 'testato e funzionante.

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

Si prega di sostituire i valori appropriati.

Si può anche semplicemente fare

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

Non è sicuro ed è una soluzione alternativa non è adatto per l'ambiente dal vivo come esso disattiverà conosciuto a livello mondiale le chiavi host di controllo.

Basta sostituire "user", "pass", "SSHD_IP". E creare un file chiamato known_hosts.txt con il contenuto del del server ~ / .ssh / known_hosts. Si otterrà una shell.

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

Ho perso un sacco di tempo su questo tema stupido, e penso che il messaggio è abbastanza giusto "non v'è l'ospite nel file sto Accedendo a", ma è possibile avere più di un file know_host intorno sul vostro sistema ( come ad esempio sto usando MobaXterm e mantenere il proprio dentro la directory di installazione di montaggio della casa da quella radice).

Se si verificano: si sta lavorando da linea di comando, ma non costituiscono l'applicazione tenta di accedere al server remoto con ssh e verificare con l'opzione -v verbose quale file è attualmente utilizzato un esempio seguente:

 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

come si può vedere la chiave è stata trovata in:

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

e non nelle mie finestre casa sotto C:.. \ Users \ my_local_user \ ssh, ho semplicemente dalla fusione e allineata per risolvere il problema

Spero che questo aiuto qualcuno in futuro

  

Qualcuno è stato in grado di risolvere questo problema? Sto usando Jscp a scp file utilizzando la chiave pubblica   autenticazione (io non voglio utilizzare l'autenticazione della password). L'aiuto sarà apprezzato !!!

Questa voce StackOverflow è di circa il controllo host-chiave, e non v'è alcuna relazione con l'autenticazione a chiave pubblica.

Per quanto riguarda l'autenticazione a chiave pubblica, provare il seguente campione con il tuo pianura (non cifrato) la chiave privata,

impostazione host noto è meglio che il valore di impostazione di stampa fingure.

Quando si imposta host noto, cercare di manualmente ssh (molto prima volta, prima che corre dell'applicazione) dalla scatola si esegue l'applicazione.

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");
}
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top